1. 程式人生 > >linux執行緒退出時執行的程式(執行緒清理處理程式)簡單例子

linux執行緒退出時執行的程式(執行緒清理處理程式)簡單例子


/********************************** pthread_exit.c **************************************/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>

void exe_exit1(void *arg)
{
    printf("我是執行緒退出時要執行的程式1!");
    printf("傳遞給我的引數是:%s\n",(char *)arg);
}

void exe_exit2(void *arg)
{
    printf("我是執行緒退出時要執行的程式2!");
    printf("傳遞給我的引數是:%s\n",(char *)arg);
}

void *func()
{
    int ret;
   
    ret=pthread_detach
(pthread_self());/*使本執行緒成為分離狀態的執行緒*/
    if(ret==0)
        printf("pthread_detach呼叫成功!\n");
    else
        printf("pthread_detach調用出錯,錯誤編號:%d",ret,errno);
       
    printf("我是執行緒,已經開始啟動!\n");
    pthread_cleanup_push(exe_exit2,"給exe_exit2的引數");
    pthread_cleanup_push(exe_exit1,"給exe_exit1的引數");
    printf("pthread_cleanup_push設定完成。\n");
    printf("我是執行緒,即將退出。\n");
    pthread_exit((void *)0);

    pthread_cleanup_pop(0);/*下面兩行不能少,否則會編譯不通過,提示語法錯誤*/
    pthread_cleanup_pop(0);
//    printf("pthread_cleanup_pop設定完成。\n");
}

int main()
{
    int ret;
    pthread_t tid;
   
    pthread_create(&tid,NULL,func,NULL);
   
    sleep(2);
    exit(0);
}

編譯: gcc -o pthread_exit -lpthread pthread_exit.c
執行: ./pthread_exit

///////////////////////////////// 執行結果 //////////////////////////////////
pthread_detach呼叫成功!
我是執行緒,已經開始啟動!
pthread_cleanup_push設定完成。
我是執行緒,即將退出。
我是執行緒退出時要執行的程式1!傳遞給我的引數是:給exe_exit1的引數
我是執行緒退出時要執行的程式2!傳遞給我的引數是:給exe_exit2的引數

=============================

幾個需要說明的地方:

1、pthread_cleanup_pop的引數是0的話,表示不執行執行緒清理處理程式(但並不妨礙把棧頂存放的那個處理程式的記錄彈出,只是不執行而已),即這裡的exe_exit1和exe_exit2。因此,如果程式中的這一句pthread_exit((void *)0);
移到func函式結尾的話,exe_exit1和exe_exit2函式將不會得到執行,因為之前的兩個pthread_cleanup_pop函式已經把儲存的處理程式的記錄給清空了。再執行到pthread_exit((void *)0);的時候棧中已經沒有待執行的處理函數了。

2、雖然本程式中的pthread_cleanup_pop函式的引數是0,這兩句本身不會觸發執行緒清理處理程式(觸發執行緒清理處理程式的任務是由pthread_exit來完成的)。但是這兩句不能去掉,可以試一下把這兩句註釋掉,再編譯的話就會出現錯誤。原因估計應該是pthread_cleanup_pop必須要和pthread_cleanup_push成對出現吧。

3、我一開始把pthread_detach函式放在了main函式中,結果執行時總是提示Segmentation fault(段錯誤)。後來在網上搜索後,改為把pthread_detach函式在func函式中呼叫,問題解決。