void pthread_cleanup_push(void (*routine)(void*), void *arg);
void pthread_cleanup_pop(int execute);//这里的int参数,0是不执行push的内容,非0是执行。
原型很简单,功能跟atexit()差不多,只不过一个是线程一个是进程。
用来设置在push/pop内线程退出时要做的事情。
需要注意的问题有几点:
1,push与pop一定是成对出现的,其实push中包含"{"而pop中包含"}",少一个不行。
2,push可以有多个,同样的pop也要对应的数量,遵循"先进后出原则"。
push进去的函数可能在以下三个时机执行:
1,显示的调用pthread_exit();
或
2,在cancel点线程被cancel。
或
3,pthread_cleanup_pop()的参数不为0时。
以上动作都限定在push/pop涵盖的代码内。
前面的2个比较好理解,关键是pthread_cleanup_pop参数问题,其实int那是因为c没有bool,这里的参数只有0与非0的区别,对pthread_cleanup_pop,参数是5和10都是一样的,都是非0。对于pthread_cleanup_pop()问题,我写了以下代码讲解
-
#include"apue.h"
-
#include<pthread.h>
-
-
pthread_t ntid;
-
-
void printids(const char *s)
-
{
-
pid_t pid;
-
pthread_t tid;
-
-
pid=getpid();
-
tid=pthread_self();
-
printf("%s pid %u tid %u (0x%x)\n",s,(unsigned int)pid,(unsigned int)tid,(unsigned int)tid);
-
}
-
-
void cleanup(void *arg)
-
{
-
printf("cleanup:%s\n",(char*)arg);
-
}
-
-
void *thr_fn_1(void *arg)
-
{
-
pthread_cleanup_push(cleanup,"thread handler 1");
-
pthread_cleanup_push(cleanup,"thread handler 2");
-
printids("new thread: ");
-
if(arg)
-
pthread_exit((void*)1);
-
pthread_cleanup_pop(0);
-
pthread_cleanup_pop(0);
-
pthread_exit((void*)1);
-
}
-
-
int main()
-
{
-
int err;
-
void *tret;
-
err=pthread_create(&ntid,NULL,thr_fn_1,(void*)1);
-
if(err!=0)
-
printf("can't create thread\n");
-
printids("main thread:");
-
pthread_join(ntid,&tret);
-
return 0;
-
}
if(arg)
pthread_exit((void*)1);
这一句是一个关键点,即如果arg非0,则执行pthread_exit((void*)1);于是就依次调用了push的函数,而后面的两句pthread_cleanup_pop(0);
仅仅是为了补齐pthread_cleanup_push(),pthread_cleanup_push()与pthread_cleanup_pop()是一一配对的,如果不配对的话就不能编译通过。
运行结果为:
main thread: pid 3575 tid 356333376 (0x153d3740)
new thread: pid 3575 tid 348067584 (0x14bf1700)
cleanup:thread handler 2
cleanup:thread handler 1
阅读(1472) | 评论(0) | 转发(0) |