1. 程式人生 > >【Linux程式設計】執行緒終止

【Linux程式設計】執行緒終止

一個執行緒退出時,可以呼叫多個之前註冊的執行緒清理處理程式。使用下面兩個函式:
void pthread_cleanup_push(void (*rtn)(void *), void *arg);     // 註冊清理函式
void pthread_cleanup_pop(int execute);     // 根據引數決定是否呼叫清理函式

註冊的清理函式的呼叫順序和棧一樣,是後進先出型別的,就如同他們的名字一樣。清理函式在下列情況下會被呼叫:
  • 執行緒呼叫pthread_exit時。
  • 響應其它執行緒發來的pthread_cancel取消請求時。
  • pthread_cleanup_pop的引數不為0時。
這裡有一點需要注意,push和pop兩個函式以巨集的形式實現的,所以必須成對出現。下面是一個測試例程:
#include <stdio.h>
#include <pthread.h>
 
// 執行緒清理處理程式
void cleanup(void *arg)
{
    printf("cleanup : %s\n", (char *)arg);
}
 
void *thr_fn1(void *arg)
{
    pthread_cleanup_push(cleanup, "This is thread 1\n");
    return ((void *)1);       // 返回不會呼叫清理函式
    pthread_cleanup_pop(0); // 配對作用
}
 
void *thr_fn2(void *arg)
{
    pthread_cleanup_push(cleanup, "This is thread 2\n");
    pthread_exit((void *)2);   // exit時會呼叫清理函式
    pthread_cleanup_pop(0);     // 配對作用
}
 
void *thr_fn3(void *arg)
{
    pthread_cleanup_push(cleanup, "This is thread 3\n");
    sleep(3);               // 等待控制執行緒發出取消請求,然後呼叫清理函式
    pthread_cleanup_pop(0); // 配對作用
}
 
void *thr_fn4(void *arg)
{
    pthread_cleanup_push(cleanup, "This is thread 4\n");
    pthread_cleanup_pop(1); // 引數為0,則清理函式不被呼叫
}
 
int main(void)
{
    pthread_t tid1, tid2, tid3, tid4;
 
    pthread_create(&tid1, NULL, thr_fn1, NULL);
    pthread_create(&tid2, NULL, thr_fn2, NULL);
    pthread_create(&tid3, NULL, thr_fn3, NULL);
    pthread_create(&tid4, NULL, thr_fn4, NULL);
 
    pthread_cancel(tid3);
 
    sleep(3);
 
    return 0;
}

執行結果: