?
一、線程清理函數
#include <pthread.h>
void ptread_clean_push(void (*rtn) (void *), void *arg); 注冊清理函數,押棧
void ptread_clean_pop(int excute); 清理函數,出棧
分析:這兩個函數是成對出現的,少一個會導致編譯不通過
參數詳解:
- pthread_cleanup_push:該函數的第一個參數是清理函數,參數是void*,返回值是void類型的,第二個函數是押棧需要傳的參數。
- pthread_cleanup_pop:出棧,調用清理函數,其中只有一個參數,該參數是非零會響應清理函數,是0的話,不做處理
注意該處理函數是被放在棧區,所以先進棧的后出棧,也就是說先進棧的函數,最后被調用。
當有以下三種操作的時候會調用清理函數:
- 調用pthread_exit()函數,會響應清理處理函數。
- 用非零的函數調用pthread_cleanup_pop()函數。
- 響應取消請求。
?
二、程序清單
測試代碼:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>void *first_cleanup(void *arg)
{printf("this is clenup function %s\n", arg);
}void *second_cleanup(void *arg)
{printf("this is clenup function %s\n", arg);
}void *thread_fun1(void *arg)
{sleep(1);printf("this is thread 1\n");pthread_cleanup_push(&first_cleanup, "thread 1");pthread_cleanup_push(&second_cleanup, "thread 1"); pthread_cleanup_pop(1);pthread_cleanup_pop(1); return (void*)0;} void *thread_fun2(void *arg)
{ sleep(2);printf("this is thread 2\n");pthread_cleanup_push(&first_cleanup, "thread 2");pthread_cleanup_push(&second_cleanup, "thread 2");pthread_exit((void*)0);pthread_cleanup_pop(0);pthread_cleanup_pop(0); } void *thread_fun3(void *arg)
{sleep(3);printf("this is thread 3\n");pthread_cleanup_push(&first_cleanup, "thread 3");pthread_cleanup_push(&second_cleanup, "thread 3");pthread_cleanup_pop(0);pthread_cleanup_pop(0); pthread_exit((void*)0); } int main(){pthread_t tid1, tid2, tid3;pthread_create(&tid1, NULL, thread_fun1, NULL);pthread_create(&tid2, NULL, thread_fun2, NULL);pthread_create(&tid3, NULL, thread_fun3, NULL);pthread_join(tid1, NULL);pthread_join(tid2, NULL);pthread_join(tid3, NULL);return 0;}
輸出結果:?
?
分析:pthread_cleanup_pop()中參數是非0時會調用清理處理函數,當參數是0的時候,pthread_cleanup_pop該函數的參數在pthread_exit()退出前調用無論是0還是非0,都會響應清理處理函數,但是pthread_exit()在pthread_cleanup_pop函數之后調用,pthread_cleanup_pop函數的參數是0的話,清理函數已經退出,所以就不會再調用到清理處理函數了。
?
三、參考資料
1.?線程的清理處理程序