Linux執行緒之pthread join

2021-07-24 04:16:36 字數 4083 閱讀 6923

linux執行緒之pthread_join

pthread_join使乙個執行緒等待另乙個執行緒結束。

**中如果沒有pthread_join;主線程會很快結束從而使整個程序結束,從而使建立的執行緒沒有機會開始執行就結束了。加入pthread_join後,主線程會一直等待直到等待的執行緒結束自己才結束,使建立的執行緒有機會執行。

所有執行緒都有乙個執行緒號,也就是threadid,其型別為pthread_t。 通過呼叫pthread_self()函式可以獲得自身的執行緒號。

如果你的主線程,也就是main函式執行的那個執行緒,在你其他執行緒退出之前就已經退出,那麼帶來的bug則不可估量。通過pthread_join函式會讓主線程阻塞,直到所有執行緒都已經退出。

int pthread_join(pthread_t thread, void **value_ptr);

thread:等待退出執行緒的執行緒號。

value_ptr:退出執行緒的返回值。

可以通過pthread_join()函式來使主線程阻塞等待其他執行緒退出,這樣主線程可以清理其他執行緒的環境。但是還有一些執行緒,更喜歡自己來清理退出 的狀態,他們也不願意主線程呼叫pthread_join來等待他們。我們將這一類執行緒的屬性稱為detached(分離的)。如果我們在呼叫 pthread_create()函式的時候將屬性設定為null,則表明我們希望所建立的執行緒採用預設的屬性,也就是jionable(此時不是detached)。

如果需要將屬性 設定為detached。則應該如下設定:

pthread_attr_t  attr;

pthread_attr_init(&attr);

pthread_attr_setdetachstate(&attr, pthread_create_detached);

pthread_create(&pthreadid, &attr, myprocess, &arg);

警告:

執行緒可以通過自身執行結束來結束,也可以通過呼叫pthread_exit()來結束執行緒的執行。另外,執行緒甲可以被執行緒乙被動結束。這個通過呼叫pthread_cancel()來達到目的。

int pthread_cancel(pthread_t thread);

函式呼叫成功返回0。

當然,執行緒也不是被動的被別人結束。它可以通過設定自身的屬性來決定如何結束

執行緒的被動結束分為兩種,一種是非同步終結,另外一種是同步終結。非同步終結就是當其他執行緒呼叫pthread_cancel的時候,執行緒就立刻被結束。而同 步終結則不會立刻終結,它會繼續執行,直到到達下乙個結束點(cancellation point)。當乙個執行緒被按照預設的建立方式建立,那麼它的屬性是同步終結。

執行緒終止的三種方式:

執行緒只是從啟動例程中返回,返回值是執行緒的退出碼;

執行緒呼叫了pthread_exit函式;

執行緒可以被同一程序中的其他執行緒取消。

1 執行緒取消的定義

一般情況下,執行緒在其主體函式退出的時候會自動終止,但同時也可以因為接收到另乙個執行緒發來的終止(取消)請求而強制終止。

2 執行緒取消的語義

執行緒取消的方法是向目標執行緒發cancel訊號,但如何處理cancel訊號則由目標執行緒自己決定,或者忽略(當禁止取消時)、或者立即終止(當在取消點 或非同步模式下)、或者繼續執行至cancelation-point(取消點,下面將描述),總之由不同的cancelation狀態決定。

執行緒接收到cancel訊號的預設處理(即pthread_create()建立執行緒的預設狀態)是繼續執行至取消點再處理(退出),或在非同步方式下直接 退出。乙個執行緒處理cancel請求的退出操作相當於pthread_exit(pthread_canceled)。當然執行緒可以通過設定為 pthread_cancel_disable來拒絕處理cancel請求,稍後會提及。

執行緒的取消與執行緒的工作方式(joinable或detached)無關。

3 取消點

根據posix標準,pthread_join()、 pthread_testcancel()、pthread_cond_wait()、 pthread_cond_timedwait()、sem_wait()、sigwait()等函式以及read()、write()等會引起阻塞的系 統呼叫都是cancelation-point,而其他pthread函式都不會引起cancelation動作。但是pthread_cancel的手冊頁聲稱,由於linuxthread庫與c庫結合得不好,因而目前c庫函式都不是cancelation-point;但cancel訊號會使執行緒從阻塞的系統呼叫中退出,並置eintr錯誤碼,因此可以在需要作為cancelation-point的系統呼叫前後呼叫pthread_testcancel(),從而達到posix標準所要求的目標,即如下**段:

pthread_testcancel();

retcode = read(fd, buffer,length);

pthread_testcancel();

使用前 須判斷執行緒id的有效性!即判斷並保證:thrd != 0 否則有可能會出現「段錯誤」的異常!

但是pthread_cancel的手冊頁聲稱,由於linuxthread庫與c庫結合得不好,因而目前c庫函式(比如read())在linux中都不是cancelation-point;但cancel訊號會使執行緒從阻塞的系統呼叫中退出,並置eintr錯誤碼,因此可以在需要作為cancelation-point的系統呼叫前後呼叫 pthread_testcancel(),從而達到posix標準所要求的目標,即如下**段:

pthread_testcancel();

retcode = read(fd, buffer, length);

pthread_testcancel();

4 程式設計方面的考慮

如果執行緒處於無限迴圈中,且迴圈體內沒有執行至取消點的必然路徑,則執行緒無法由外部其他執行緒的取消請求而終止。因此在這樣的迴圈體的必經路徑上應該加入pthread_testcancel()呼叫。

當pthread_cancel()返回時,執行緒未必已經取消,可能僅僅將請求傳送給目標執行緒,而目標執行緒目前沒有到達取消點,如果要知道執行緒在何時中止,就需要在取消它之後呼叫pthread_join()。有乙個例外是當執行緒被detach後,不能這樣處理:

a) 當join乙個已經detached的執行緒時,返回einval;

b) 如果join後該執行緒設定為detached,則detach將不起作用。

因此,如果知道乙個執行緒可能會以分離方式執行,就不需要在pthread_cancel()後呼叫pthread_join()。

5 與執行緒取消相關的pthread函式

int pthread_cancel(pthread_t thread)

傳送終止訊號給thread執行緒,如果成功則返回0,否則為非0值。傳送成功並不意味著thread會終止。

int pthread_setcancelstate(int state, int *oldstate)

設 置本執行緒對cancel訊號的反應,state有兩種值:pthread_cancel_enable(預設)和 pthread_cancel_disable,分別表示收到訊號後設為cancled狀態和忽略cancel訊號繼續執行;old_state如果不為 null則存入原來的cancel狀態以便恢復。

int pthread_setcanceltype(int type, int *oldtype)

設 置本執行緒取消動作的執行時機,type有兩種取值:pthread_cancel_deffered 和 pthread_cancel_asychronous,僅當cancel狀態為enable時有效,分別表示收到訊號後繼續執行至下乙個取消點再退出和 立即執行取消動作(退出);oldtype如果不為null則存入運來的取消動作型別值。

void pthread_testcancel(void)

檢查本執行緒是否處於canceld狀態,如果是,則進行取消動作,否則直接返回。

6 檢測乙個執行緒是否還活著的pthread函式

Linux 多執行緒 pthread

1.linux執行緒的發展 早在linux2.2核心中。並不存在真正意義上的執行緒,當時linux中常用的執行緒pthread實際上是通過程序來模擬的,也就是同過fork來建立 輕 程序,並且這種輕程序的執行緒也有個數的限制 最多只能有4096和此類執行緒同時執行。2.4核心消除了個數上的限制,並且...

C C 多執行緒程式設計之四 終止pthread執行緒

多執行緒程式設計之終止pthread執行緒 pthread是posix threads的簡稱,是posix的執行緒標準。終止執行緒似乎是多執行緒程式設計的最後一步,但絕不是本系列教材的結束。執行緒建立到執行緒終止,希望先給讀者乙個關於多執行緒程式設計的整體認識。1.終止pthread執行緒 pthr...

多執行緒程式設計之pthread執行緒深入理解

不同的平台和作業系統上 程序和執行緒的實現機制不完全一致 但是一般來說執行緒棧都是獨立的 只要得到位址就可以相互訪問 pthread是 posix threads 的簡稱,是posix的執行緒標準。前幾篇部落格已經能給你初步的多執行緒概念,在進一步學習執行緒同步等多執行緒核心知識之前,需要對多執行緒...