pthread_clean_push与pthread_cleanup_pop函数详解

测试,使用word2010发送博客文章

 

http://www.cnblogs.com/你的博客名称/services/metablogapi.aspx

 

转载http://blog.chinaunix.net/uid-26772137-id-3369725.html

  1. #include <pthread.h>
  2. void pthread_cleanup_push(void( *fn)(void*)),(void* arg))
  3.  
  4. void pthread_cleanup_pop(int excute)
  5. 两个函数可以安排执行线程退出后需要执行的清理函数,这两个函数和进程退出时的atexit很像。
  6.  
  7. 点击(此处)折叠或打开
  8. #include <stdlib.h>
  9. atexit(void(*fn)(void ))
  10. "线程取消函数"即线程被取消或者下面描述的情况发生时自动调用的函数。它一般用于释放一些资源,比如释放锁,以免其它的线程永远也不能获得锁,而造成死锁。
  11. pthread_cleanup_push()函数执行压栈清理函数的操作,而pthread_cleanup_pop()函数执行从栈中删除清理函数的操作。
  12. 在下面三种情况下,pthread_cleanup_push()压栈的"清理函数"会被调用:
  13. 1, 线程调用pthread_exit()函数,而不是直接return.
  14. 2, 响应取消请求时,也就是有其它的线程对该线程调用pthread_cancel()函数。
  15. 3, 本线程调用pthread_cleanup_pop()函数,并且其参数非0
  16. 注意:
  17. 1.pthread_cleanup_pop()函数的参数为0时,仅仅在线程调用pthread_exit函数或者其它线程对本线程调用
  18. pthread_cancel函数时,才在弹出"清理函数"的同时执行该"清理函数"。
  19. 2.注意pthread_exit终止线程与线程直接return终止线程的区别,调用return函数是不会在弹出"清理函数"的同时执行该"清理函数的。
  20. 3 .pthread_cleanup_push()函数与pthread_cleanup_pop()函数必须成对的出现在同一个函数中。
  21. 例子1.
  22.  
  23. include <pthread.h>
  24.  
  25. #include <sys/types.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <unistd.h>
  29. #include <errno.h>
  30.  
  31. #define handle_error_en(en, msg) \
  32. do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
  33.  
  34. static int done = 0;
  35. static int cleanup_pop_arg = 0;
  36. static int cnt = 0;
  37.  
  38. static void cleanup_handler(void *arg)
  39. {
  40. printf("Called clean-up handler\n");
  41. cnt = 0;
  42. }
  43.  
  44. static void *thread_start(void *arg)
  45. {
  46. time_t start, curr;
  47.  
  48. printf("New thread started\n");
  49. pthread_cleanup_push(cleanup_handler, NULL);
  50. curr = start = time(NULL);
  51. while(!done){
  52. pthread_testcancel(); /* A cancellation point */
  53. if(curr < time(NULL)){
  54. curr = time(NULL);
  55. printf("cnt = %d\n", cnt); /* A cancellation point */
  56. cnt++;
  57. }
  58. }
  59.  
  60. pthread_cleanup_pop(cleanup_pop_arg);
  61. return NULL;
  62. }
  63.  
  64. int main(int argc, char *argv[])
  65. {
  66. pthread_t thr;
  67. void *res;
  68.  
  69. pthread_create(&thr, NULL, thread_start, NULL);
  70. sleep(2); /* Allow new thread to run a while */
  71.  
  72. if(argc > 1){
  73. if(argc > 2)
  74. cleanup_pop_arg = atoi(argv[2]);
  75. done = 1;
  76.  
  77. }else{
  78. printf("Canceling thread\n");
  79. pthread_cancel(thr);
  80. }
  81.  
  82. pthread_join(thr, &res);
  83. if(res == PTHREAD_CANCELED)
  84. printf("Thread was canceled; cnt = %d\n", cnt);
  85. else
  86. printf("Thread terminated normally; cnt = %d\n", cnt);
  87. exit(EXIT_SUCCESS);
  88. }
  89.  
  90. 点击(此处)折叠或打开
  91. #include<stdlib.h>
  92. #include<stdio.h>
  93. #include<unistd.h>
  94. #include<pthread.h>
  95. void clean_fun1(void * arg)
  96. {
  97. printf("this is clean fun1\n");
  98. }
  99. void clean_fun2(void * arg)
  100. {
  101. printf("this is clean fun2\n");
  102. }
  103. void * thread_fun(void * arg)
  104. {
  105. pthread_cleanup_push(clean_fun1,NULL);
  106. pthread_cleanup_push(clean_fun2,NULL);
  107. sleep(100);
  108. //这里要注意,如果将sleep(100);换成while(1);的话,程序会一直暂停.pushpop要成对出现.
  109. //因为while(1);运行的太快,线程不接受cancel信号
  110. //while(1);
  111. pthread_cleanup_pop(0);
  112. pthread_cleanup_pop(0);
  113. return NULL;
  114. }
  115. int main()
  116. {
  117. pthread_t tid1;
  118. int err;
  119. err=pthread_create(&tid1,NULL,thread_fun,NULL);
  120. if(err!=0)
  121. {
  122. perror("pthread_create");
  123. exit(0);
  124. }
  125. sleep(3);
  126. //printf("test\n");
  127. err=pthread_cancel(tid1);
  128. if(err!=0)
  129. {
  130. perror("cancel error:");
  131. exit(0);
  132. }
  133. err=pthread_join(tid1,NULL);
  134. if(err!=0)
  135. {
  136. perror("pthread_join error:");
  137. exit(0);
  138. }
  139.  
  140. return 0;
  141. }
posted @ 2015-03-23 23:22  語过添情  阅读(3243)  评论(1编辑  收藏  举报