作者:kangear
书籍:《UNIX环境高级编程》以下简称《UNIX书》
《C程序设计(第三版)》以下简称《C书》
thread_clean.c就是《UNIX书》上的实例,把书上的话抄下来,下次查看时方便:
程序清单11-4显示了如何使用线程清理处理程序。虽然例子有人为编造之嫌(PS:看来这样的例子只是学习用用就行了),但说清楚了其中涉及的清理机制。注意,虽然并未打算要传一个零参数给线程启动例程,还是需要把pthread_cleanup_pop调用和pthread_cleanup_push调用匹配起来,否则,程序编译可能通不过。(PS:程序国嵌有所改动)
程序清单11-4 线程清理处理程序
- #include <stdio.h>
- #include <pthread.h>
- #include <unistd.h>
- void *clean(void *arg)
- {
- printf("cleanup :%s \n",(char *)arg);
- return (void *)0;
- }
- void *thr_fn1(void *arg)
- {
- printf("thread 1 start \n");
- pthread_cleanup_push( (void*)clean,"thread 1 first handler");
- pthread_cleanup_push( (void*)clean,"thread 1 second hadler");
- printf("thread 1 push complete \n");
- if(arg)
- {
- return((void *)1);
- }
- pthread_cleanup_pop(0);
- pthread_cleanup_pop(0);
- return (void *)1;
- }
- void *thr_fn2(void *arg)
- {
- printf("thread 2 start \n");
- pthread_cleanup_push( (void*)clean,"thread 2 first handler");
- pthread_cleanup_push( (void*)clean,"thread 2 second handler");
- printf("thread 2 push complete \n");
- if(arg)
- {
- pthread_exit((void *)2);
- }
- pthread_cleanup_pop(0);
- pthread_cleanup_pop(0);
- pthread_exit((void *)2);
- }
- int main(void)
- {
- int err;
- pthread_t tid1,tid2;
- void *tret;
- err=pthread_create(&tid1,NULL,thr_fn1,(void *)1);
- if(err!=0)
- {
- printf("error .... \n");
- return -1;
- }
- err=pthread_create(&tid2,NULL,thr_fn2,(void *)1);
- if(err!=0)
- {
- printf("error .... \n");
- return -1;
- }
- err=pthread_join(tid1,&tret);
- if(err!=0)
- {
- printf("error .... \n");
- return -1;
- }
- printf("thread 1 exit code %d \n",(int)tret);
- err=pthread_join(tid2,&tret);
- if(err!=0)
- {
- printf("error .... ");
- return -1;
- }
- printf("thread 2 exit code %d \n",(int)tret);
-
- return 1;
- }
- #include <stdio.h>
- #include <pthread.h>
- #include <unistd.h>
- void *clean(void *arg)
- {
- printf("cleanup :%s \n",(char *)arg);
- return (void *)0;
- }
- void *thr_fn1(void *arg)
- {
- printf("thread 1 start \n");
- pthread_cleanup_push( (void*)clean,"thread 1 first handler");
- pthread_cleanup_push( (void*)clean,"thread 1 second hadler");
- printf("thread 1 push complete \n");
- if(arg)
- {
- return((void *)1);
- }
- pthread_cleanup_pop(0);
- pthread_cleanup_pop(0);
- return (void *)1;
- }
- void *thr_fn2(void *arg)
- {
- printf("thread 2 start \n");
- pthread_cleanup_push( (void*)clean,"thread 2 first handler");
- pthread_cleanup_push( (void*)clean,"thread 2 second handler");
- printf("thread 2 push complete \n");
- if(arg)
- {
- pthread_exit((void *)2);
- }
- pthread_cleanup_pop(0);
- pthread_cleanup_pop(0);
- pthread_exit((void *)2);
- }
- int main(void)
- {
- int err;
- pthread_t tid1,tid2;
- void *tret;
- err=pthread_create(&tid1,NULL,thr_fn1,(void *)1);
- if(err!=0)
- {
- printf("error .... \n");
- return -1;
- }
- err=pthread_create(&tid2,NULL,thr_fn2,(void *)1);
- if(err!=0)
- {
- printf("error .... \n");
- return -1;
- }
- err=pthread_join(tid1,&tret);
- if(err!=0)
- {
- printf("error .... \n");
- return -1;
- }
- printf("thread 1 exit code %d \n",(int)tret);
- err=pthread_join(tid2,&tret);
- if(err!=0)
- {
- printf("error .... ");
- return -1;
- }
- printf("thread 2 exit code %d \n",(int)tret);
-
- return 1;
- }
运行程序清单会得到:
tu1
从输出结果可以看出,两个线程都正确地启动和退出了,但是只调用了第二个线程的清理处理程序,所以如果线程是通过从它的启动例程中返回而终止的话,那么它的清理处理程序就不会被调用,还要注意清理处理程序是按照与它们安装是相反的顺序被调用。
国嵌的话:push和pop之间的程序段中的终止动作(包调用pthread_exit()和异常终止,不包括return)都将执行push所指定的清理函数。
PS:这就是为什么输出结果,只有tfr_fn2调用了清理处理程序。因为它用了pthread_exit()来退出了;这就是为什么输出结果tfr_fn1没有调用清理函数,因为它用了return退出了。
阅读(1087) | 评论(0) | 转发(0) |