红联Linux门户
Linux帮助

linux下线程异常退出后的清除问题

发布时间:2016-11-03 15:18:39来源:linux网站作者:蜜獾哥
Linux系统具备多线程功能,但是如果线程运行过程中异常退出了。有可能一些资源没有被释放,那么怎么办呢?linux下提供了专门的函数,pthread_cleanup_push和pthread_cleanup_pop函数来解决这个问题。
 
先看一下函数说明:
pthread_cleanup_push(void*(*fun)(void*),void *arg);
fun显然是一个函数指针,代表线程异常退出后会执行的函数,而arg是传递给清除函数的参数。
pthread_cleanup_pop(int execute);
如果execute为0,则pop时不执行清除函数,如果为1则执行清除函数。
你只需要把可能出现异常的代码放在push和pop函数之间就可以了,当然你需要专门写一个清除函数,下面看我的代码示例。
 
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<stdlib.h>
pthread_t tid1,tid2;
void *clean(void *arg)
{
printf("cleanup:%s\n",(char *)arg);
return NULL;
}
void *dt1(void *arg)
{
printf("thread1 start\n");
pthread_cleanup_push((void*)clean,"thread1 first clean");
pthread_cleanup_push((void*)clean,"thread1 second clean");
printf("thread1 push complete\n");
if(arg){
return (void*)1;//return被当成正常退出
}
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
return (void*)1;
}
void *dt2(void *arg)
{
printf("thread2 start\n");
pthread_cleanup_push((void*)clean,"thread2 first clean");
pthread_cleanup_push((void*)clean,"thread2 second clean");
printf("thread2 push complete\n");
if(arg){
pthread_exit((void*)2);//相当于异常退出
}
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
pthread_exit((void*)2);
}
void main()
{
void *tret;
pthread_create(&tid1,NULL,dt1,(void*)1);
pthread_join(tid1,&tret);
printf("thread1 exit code:%d\n",(int)tret);
pthread_create(&tid2,NULL,dt2,(void*)1);
pthread_join(tid2,&tret);
printf("thread2 exit code:%d\n",(int)tret);
}
 
编译执行后打印结果如下:
thread1 start
thread1 push complete
thread1 exit code:1
thread2 start
thread2 push complete
cleanup:thread2 second clean
cleanup:thread2 first clean
thread2 exit code:2
 
为什么呢?由程序可见,thread1的push和pop之间确实也退出了,单采用了return,所以认为不是异常退出。而thread2采用了pthread_exit函数,则被认为是异常退出,因此执行了清除函数。那么如何也能让thread1执行清除函数呢?只需要将红色部分代码改为如下:
 
/*if(arg){
return (void*)1;//return被当成正常退出
}*/
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
 
你会发现thread1也执行了清除函数。原因很简单,线程1执行到了pop函数,当然不是异常退出了。但是pop函数的参数为1,因此依然执行了清除函数。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/25697.html