Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1731879
  • 博文数量: 782
  • 博客积分: 2455
  • 博客等级: 大尉
  • 技术积分: 4140
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-06 21:37
个人简介

Linux ,c/c++, web,前端,php,js

文章分类

全部博文(782)

文章存档

2015年(8)

2014年(28)

2013年(110)

2012年(307)

2011年(329)

分类:

2012-04-21 11:40:50

作者:kangear

书籍:《UNIX环境高级编程》以下简称《UNIX书》

             C程序设计(第三版)》以下简称《C书》

 

thread_clean.c就是《UNIX书》上的实例,把书上的话抄下来,下次查看时方便:

   

     程序清单11-4显示了如何使用线程清理处理程序。虽然例子有人为编造之嫌(PS:看来这样的例子只是学习用用就行了),但说清楚了其中涉及的清理机制。注意,虽然并未打算要传一个零参数给线程启动例程,还是需要把pthread_cleanup_pop调用和pthread_cleanup_push调用匹配起来,否则,程序编译可能通不过。(PS:程序国嵌有所改动)

 

               程序清单11-4 线程清理处理程序

 


点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <pthread.h>
  3. #include <unistd.h>
  4. void *clean(void *arg)
  5. {
  6.     printf("cleanup :%s \n",(char *)arg);
  7.     return (void *)0;
  8. }
  9. void *thr_fn1(void *arg)
  10. {
  11.     printf("thread 1 start \n");
  12.     pthread_cleanup_push( (void*)clean,"thread 1 first handler");
  13.     pthread_cleanup_push( (void*)clean,"thread 1 second hadler");
  14.     printf("thread 1 push complete \n");
  15.     if(arg)
  16.     {
  17.         return((void *)1);
  18.     }
  19.     pthread_cleanup_pop(0);
  20.     pthread_cleanup_pop(0);
  21.     return (void *)1;
  22. }


  23. void *thr_fn2(void *arg)
  24. {
  25.     printf("thread 2 start \n");
  26.     pthread_cleanup_push( (void*)clean,"thread 2 first handler");
  27.     pthread_cleanup_push( (void*)clean,"thread 2 second handler");
  28.     printf("thread 2 push complete \n");
  29.     if(arg)
  30.     {
  31.         pthread_exit((void *)2);
  32.     }
  33.     pthread_cleanup_pop(0);
  34.     pthread_cleanup_pop(0);
  35.     pthread_exit((void *)2);
  36. }


  37. int main(void)
  38. {
  39.     int err;
  40.     pthread_t tid1,tid2;
  41.     void *tret;

  42.     err=pthread_create(&tid1,NULL,thr_fn1,(void *)1);
  43.     if(err!=0)
  44.     {
  45.         printf("error .... \n");
  46.         return -1;
  47.     }
  48.     err=pthread_create(&tid2,NULL,thr_fn2,(void *)1);

  49.     if(err!=0)
  50.     {
  51.         printf("error .... \n");
  52.         return -1;
  53.     }
  54.     err=pthread_join(tid1,&tret);
  55.     if(err!=0)
  56.     {
  57.         printf("error .... \n");
  58.         return -1;
  59.     }
  60.     printf("thread 1 exit code %d \n",(int)tret);

  61.     err=pthread_join(tid2,&tret);
  62.     if(err!=0)
  63.     {
  64.         printf("error .... ");
  65.         return -1;
  66.     }

  67.     printf("thread 2 exit code %d \n",(int)tret);
  68.     
  69.     return 1;
  70. }

  71. #include <stdio.h>
  72. #include <pthread.h>
  73. #include <unistd.h>
  74. void *clean(void *arg)
  75. {
  76.     printf("cleanup :%s \n",(char *)arg);
  77.     return (void *)0;
  78. }
  79. void *thr_fn1(void *arg)
  80. {
  81.     printf("thread 1 start \n");
  82.     pthread_cleanup_push( (void*)clean,"thread 1 first handler");
  83.     pthread_cleanup_push( (void*)clean,"thread 1 second hadler");
  84.     printf("thread 1 push complete \n");
  85.     if(arg)
  86.     {
  87.         return((void *)1);
  88.     }
  89.     pthread_cleanup_pop(0);
  90.     pthread_cleanup_pop(0);
  91.     return (void *)1;
  92. }


  93. void *thr_fn2(void *arg)
  94. {
  95.     printf("thread 2 start \n");
  96.     pthread_cleanup_push( (void*)clean,"thread 2 first handler");
  97.     pthread_cleanup_push( (void*)clean,"thread 2 second handler");
  98.     printf("thread 2 push complete \n");
  99.     if(arg)
  100.     {
  101.         pthread_exit((void *)2);
  102.     }
  103.     pthread_cleanup_pop(0);
  104.     pthread_cleanup_pop(0);
  105.     pthread_exit((void *)2);
  106. }


  107. int main(void)
  108. {
  109.     int err;
  110.     pthread_t tid1,tid2;
  111.     void *tret;

  112.     err=pthread_create(&tid1,NULL,thr_fn1,(void *)1);
  113.     if(err!=0)
  114.     {
  115.         printf("error .... \n");
  116.         return -1;
  117.     }
  118.     err=pthread_create(&tid2,NULL,thr_fn2,(void *)1);

  119.     if(err!=0)
  120.     {
  121.         printf("error .... \n");
  122.         return -1;
  123.     }
  124.     err=pthread_join(tid1,&tret);
  125.     if(err!=0)
  126.     {
  127.         printf("error .... \n");
  128.         return -1;
  129.     }
  130.     printf("thread 1 exit code %d \n",(int)tret);

  131.     err=pthread_join(tid2,&tret);
  132.     if(err!=0)
  133.     {
  134.         printf("error .... ");
  135.         return -1;
  136.     }

  137.     printf("thread 2 exit code %d \n",(int)tret);
  138.     
  139.     return 1;
  140. }


 

运行程序清单会得到:

tu1

 

 

从输出结果可以看出,两个线程都正确地启动和退出了,但是只调用了第二个线程的清理处理程序,所以如果线程是通过从它的启动例程中返回而终止的话,那么它的清理处理程序就不会被调用,还要注意清理处理程序是按照与它们安装是相反的顺序被调用。

国嵌的话:pushpop之间的程序段中的终止动作(包调用pthread_exit()和异常终止,不包括return)都将执行push所指定的清理函数。

PS:这就是为什么输出结果,只有tfr_fn2调用了清理处理程序。因为它用了pthread_exit()来退出了;这就是为什么输出结果tfr_fn1没有调用清理函数,因为它用了return退出了。

阅读(1087) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~