一、线程的基本概念
1、基本概念
线程是特殊的进程,在操作系统中,线程不能独立存在,线程是进程创建出来的,一个进程可以有多个线程,进程退出了,线程也会跟着退出。
2、资源
每个进程都有自己独立的堆、栈、数据段、代码段等空间,线程基本没有独立的资源,只有必不可少的资源(栈),同一进程之间的线程共享进程中的所有资源。
二、线程相关的API
1、线程创建函数 thread:存放线程的id attr:线程的分离属性—>NULL start_routine :参数为void *, 返回值也是void * 类型的函数指针。(线程执行函数) arg:函数的参数 返回值:成功返回0,失败返回非0. 代码段:
void * Pthread_Task(void *arg)
{
int a = (long)arg;
printf("-----%d\n", a);
}
int main()
{
long data = 110;
pthread_t pid;
int ret = pthread_create(&pid, NULL, Pthread_Task, (void *)data);
if(ret != 0)
{
perror("ptread_create");
return -1;
}
else
{
printf("线程创建成功!\n");
}
}
2、线程的退出 retal: 返回线程结束的状态(void*变量) 让线程退出的三种方法:
- 线程的任务函数调用完返回退出(直接死),让其他人给这个死的线程回收线程资源.线程调用这个pthread_exit();
立马死了,让其他人给这个死的线程回收线程资源. - 取消线程 pthreada_cancel:只是一个请求(不能保证线程肯定会去退出)
- 设置线程位分离属性,他死了不需要别人给他收尸。
3、线程资源回收函数 thread: 子线程的id retval: 子线程结束状态 等待回收子线程的资源(栈空间),作用相当于子线程中的waitpid pthread_join:默认是堵塞的,自己不能调用pthread_join来回收自己。 4、设置线程分离属性 1)分离属性:子线程的资源由系统回收,线程的资源回收需使用pthread_join来实现,如果该线程运行没有结束,会阻塞主线程,当主线程还要创建新线程来做一些事情,此时主线程就会因为调用pthread_join而被堵塞,就没办法处理其他事务,所以引入线程的分离属性,他不需要主线程回收,在退出系统会自动回收。 线程分离函数: int pthread_detach(pthread_t thread); thread:线程id 2)线程创建时选择分离属性-----对pthread_create的第二个参数进行设置 pthread_attr_t *attr 定义一个pthread_attr_t 类型变量attr,然后对这个变量attr 进行初始化 pthread_attr_init()最后设置分离属性。 ① 初始化线程属性 int pthread_attr_init(pthread_attr_t *attr); ② 设置分离属性 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); 5、线程的取消 1)线程取消函数:pthread_cancel() 2)设置线程取消响应—>是否响应取消信号 3)设置响应取消信号的类型---->立即响应、延时响应 代码段:
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
struct Data
{
char pthread_name[10];
};
void *Pthread_Task(void *arg)
{
int pthread_setcancelstate_ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
if (pthread_setcancelstate_ret != 0)
{
perror("pthread_setcancelstate");
exit(-1);
}
while (1)
{
struct Data *p = (struct Data *)arg;
printf("%s\n", p->pthread_name);
sleep(1);
}
pthread_exit(NULL);
}
int main()
{
pthread_t pid;
struct Data d1;
memset(&d1, 0, sizeof(d1));
strcpy(d1.pthread_name, "hello");
int ret = pthread_create(&pid, NULL, Pthread_Task, (void *)&d1);
if (ret != 0)
{
perror("pthread_create");
exit(-1);
}
printf("5s之后发送取消请求\n");
sleep(5);
pthread_cancel(pid);
pause();
return 0;
}
压栈和弹栈要配套使用,想让谁响应注册函数,那么就是谁里面写压栈和弹栈。 代码段:
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
void Pthread_At_Fun(void *arg)
{
printf("%s\n", (char *)arg);
}
void *Pthread_Task(void *arg)
{
pthread_cleanup_push(Pthread_At_Fun, (void *)"死亡闪现");
printf("三秒之后我将死亡\n");
sleep(3);
pthread_exit(NULL);
pthread_cleanup_pop(0);
}
int main()
{
pthread_t pid;
int pthread_create_ret = pthread_create(&pid, NULL, Pthread_Task, NULL);
if(pthread_create_ret != 0)
{
perror("pthread_create");
exit(-1);
}
while(1)
{
printf("我看见小线程死亡闪现!\n");
sleep(1);
}
return 0;
}
|