2011-06-08 119 views
36

我想爲給定的線程ID調用pthread_join,但只有在該線程已經啓動的情況下。安全的解決方案可能是添加一個變量來跟蹤哪個線程開始或未開始。但是,我想知道是否可以檢查pthread_t變量,如下面的代碼。是否有無效的pthread_t ID?

pthread_t thr1 = some_invalid_value; //0 ? 
pthread_t thr2 = some_invalid_value; 

/* thread 1 and 2 are strated or not depending on various condition */ 
.... 

/* cleanup */ 
if(thr1 != some_invalid_value) 
    pthread_join(&thr1); 

if(thr2 != some_invalid_value) 
    pthread_join(&thr2); 

凡some_invalid_value可能是0,或者依賴於實現 'PTHREAD_INVALID_ID' 宏觀

PS: 我的假設是的pthread_t類型是可比的,可轉讓的假設基礎上

PPS: 我想這樣做,因爲我認爲調用無效線程ID上的pthread_join是不確定的行爲。不是這樣。但是,加入之前加入的線程是未定義的行爲。現在讓我們假設重複調用上述「功能」。 無條件地調用pthread_join並檢查結果可能會導致在以前連接的線程上調用pthread_join。

+5

你總是可以使用pthread_self()......一個線程,你想必不會加盟;-)。可以使用'pthread_t invalid_thread = pthread_self()'來提高可讀性。 – 2011-06-08 09:50:55

回答

15

您的假設是不正確的開始。 pthread_t對象是不透明的。您無法直接在C中比較pthread_t類型。您應該使用pthread_equal。

另一個考慮是,如果pthread_create失敗,pthread_t的內容將不確定。它可能不會再被設置爲無效值。

我的首選是保持pthread_create調用的返回值(以及線程ID)並使用它來確定每個線程是否正確啓動。

+0

您**可以直接在C. [sys/types.h](http://pubs.opengroup.org/onlinepubs/007908799/xsh/systypes.h.html)中比較pthread_t類型,將所有類型定義爲算術類型(有些例外排除了pthread_t)。我認爲你的意思是你**不應該**比較pthread_t類型 – OLL 2016-01-22 10:44:02

10

正如Tony所建議的那樣,在這種情況下可以使用pthread_self()。使用==!=。使用pthread_equal

pthread_self手冊頁:

因此,類型的pthread_t的變量不能便攜被使用C相等運算(==)比較;改爲使用pthread_equal(3)。

+2

+1 - 只是爲了詳細闡述qbert220的建議,使用單獨的標誌來跟蹤無效的線程,這裏的用法是:'if(pthread_create(&thr,...)!= 0)thr = pthread_self();'。 – 2011-06-09 00:46:12

1

不幸的是,在pthread_t是指針的系統上,即使兩個參數指向不同的線程,pthread_equal()也可以返回相等性。一個線程可以退出,並且可以使用相同的pthread_t指針值創建一個新的線程。

+0

當然,直接比較在這種情況下也會失敗。 :-) – FooF 2013-07-12 04:36:24

1

我最近遇到了同樣的問題。如果pthread_create()失敗,我最終會在我的phtread_t結構中存儲一個未定義的無效值。因此,如果pthread_create()成功,我會保持與每個線程關聯的布爾值。

然後,所有我需要做的是:

void* status; 
if (my_thread_running) { 
    pthread_join(thread, &status); 
    my_thread_running = false; 
}