开发者学堂课程【物联网开发- Linux 高级程序设计全套视频:线程 pthread_exit 时执行清理程序】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/660/detail/11067
线程 pthread_exit 时执行清理程序
内容介绍:
一、调用 pthread_exit 退出线程
二、响应其他线程的取消请求
一、调用 pthread_exit 退出线程
1、验证线程调用 pthread_exit 函数时,系统自动调用线程清理函数
以线程执行 pthread_exit “自杀”时,系统自动调用线程清理函数的这个例子,在这个程序中体现效果。
在 main 函数中
int main(int argc, char *argv[ ])
{
pthread_t tid;
pthread_create(&tid, NULL, thread, NULL);//创建一个线程
pthread_join(tid,NULL);//等待线程结束
printf("prosses is dying\n");//打印一句话线程结束
return 0;
}
在线程函数中
void *thread(void *arg)
{
char *ptr = NULL;
/*建立线程清理程序*/
printf("this is new thread\n");
//打印一句提示信息(this is new thread)
ptr = (char*)malloc(100); //在 malloc 申请100个字节
pthread_cleanup_push(cleanup, (void*) (ptr));//注册了一个清理函数,ptr 给 cleanup 传参
bzero(ptr, 100);
//初始化100个字节
strcpy(ptr, "memory from malloc");
//调用这100个字节
printf("before exit\n");
//打印一句话
pthread_exit(NULL);
//调用此函数“自杀”,“自杀”后下面的代码没有机会执行
sleep(3);
/*注意 push 与 pop 必须配对使用(有几个 push,就有几个 pop),即使 pop 执行不到,否则编译会出错*/
printf("before pop\n");
pthread_cleanup_pop(1);
return NULL;
}
在创建线程后,执行到 pthread_exit(NULL) 语句时,线程“自杀”,之后调用 cleanup 函数,将指针内存释放。
void cleanup(void *arg)
{
printf("clean up ptr = %s\n", (char *)arg);
//执行 clean up ptr,打印了传过来的字符串
free((char *)arg);
//将指针指向的内存释放,malloc 中内存在此处释放。
}
验证 cleanup 能否被执行,
由运行结果可知执行到了清理函数
2、验证注册多个清理函数的执行顺序
void cleanup(void *arg)
{
printf("clean up ptr = %s\n", (char *)arg);
free((char *)arg);
}
//复制另外两个清理函数
void cleanup(void *arg)
{
printf("in clean up2\n");
}
void cleanup(void *arg)
{
printf("in clean up3\n");
}
void *thread(void *arg)
{
char *ptr = NULL;
/*建立线程清理程序*/
printf("this is new thread\n");
ptr = (char*)malloc(100);
pthread_cleanup_push(cleanup, (void*) (ptr));
//继续注册两个清理函数
pthread_cleanup_push(cleanup2, (void*) (ptr));
pthread_cleanup_push(cleanup3, (void*) (ptr));
//先注册1,2,3;运行时为3,2,1
bzero(ptr, 100);
strcpy(ptr, "memory from malloc");
printf("before exit\n");
pthread_exit(NULL);
sleep(3);
printf("before pop\n");
pthread_cleanup_pop(1);
//加两个 pop,使 pop 与 push 配对
pthread_cleanup_pop(1);
pthread_cleanup_pop(1); return NULL;
}
一运行线程马上“自杀”,调用 pthread_exit 时会去执行清理函数,而且执行顺序为先注册的后执行,后注册的先执行。
二、响应其他线程的取消请求。
通过修改代码验证清理函数的执行情况
将上述代码中的 pthread_exit(NULL) 改为return NULL
验证调用 return 函数时是否执行清理函数,
运行结果如下:
由运行结果可知清理函数没有被执行,所以调用 return 使线程结束这种情况,清理函数不会被执行。
