2012-08-14 68 views
-5

是否合法作出atexit電話pthread_exit?沒有它時main()返回所有的線程被終止。 (瑣細的解決辦法是修改main()打電話pthread_exit()本身,而這是不可能在這個小例子,從獲得的情況下)。使用的atexit調用了pthread_exit

#include <unistd.h> 
#include <cstdlib> 
#include <iostream> 
#include <pthread.h> 

void *foo(void *data) { 
    for (int i = 0; i < 10; ++i) { 
    std::cout << i << "\n"; 
    sleep(1); 
    } 
    return NULL; 
} 

void foo_init() { 
    std::atexit([](){ 
    pthread_exit(NULL); 
    }); 
} 

int main() { 
    foo_init(); 
    pthread_attr_t attr; 
    pthread_attr_init(&attr); 
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 
    pthread_t thr; 
    pthread_create(&thr, &attr, foo, NULL); 
} 

pthread_exit狀態的手冊頁:

線程終止不釋放任何應用程序可見的進程資源,包括但不限於,互斥體和文件描述符,也不會執行任何進程級別的清理動作,包括但不限於調用任何可能存在的atexit()例程。

這似乎排除瘋狂遞歸破壞事物的風險。

報告還指出:

了pthread_exit的行爲()是不確定的,如果從被援引作爲隱式或顯式調用的結果了pthread_exit取消清理處理或析構函數稱爲()。

這表明有地方將是不確定的調用pthread_exit地方,但(除非主需要> 10秒的回報,這讓我們假設是不可能的「真實」情況)不適用。

這個例子「爲我的作品」,但需要通過POSIX工作?如果不是未定義或未指定?

回答

4

有一些問題就POSIX而言:

  • docs for pthread_exit()說:「這個過程爲0的狀態退出最後一個線程終止後的行爲就如同實施叫出口()與線程終止時間爲零的說法「
  • docs for exit()說,」如果通過調用)註冊的atexit(功能未能返回,其餘的註冊功能不應被調用和出口的休息()處理不應該完成,如果exit()被多次調用,行爲是不確定的「。

所以嚴格來說,當pthread_exit()被稱爲最後一個線程,該行爲將彷彿exit()被稱爲一次以上,這是說這是不確定的行爲。

不過,我想,應該發生的最糟糕的是,應用程序會崩潰或死鎖時,最後一個線程退出。由於該過程正在退出,所以根據您的應用程序的性質以及您的測試指示的風險程度有多低,風險可能是可接受的。

如果您可以安排知道哪個線程將是最後退出,我認爲您可以阻止信號量,條件變量或atexit()回調中的互斥,而不是調用pthread_exit()。當它打算撥打pthread_exit()(或返回)時,讓最後一個線程釋放該塊。