posix執行緒 執行緒的取消

2021-07-03 14:58:38 字數 2783 閱讀 1832

初看這個主題時,覺得實在簡單。在我印象中,執行緒取消的實現通常是宣告乙個全域性變數來代表取消標誌,乙個執行緒在最開始的大while中判斷該標誌是否被設定,如果被設定就跳出迴圈。但是這有乙個問題是,如果程式中有n個執行緒都有可能被取消,那麼我們是否要宣告n個全域性變數來單獨控制它們的取消?posix提供了一些有效的api來簡化我們對執行緒取消的操作(不過這背後還是有很多複雜的概念)。從很多書上把執行緒的取消單獨作為一節或一章,足可窺見它的特殊性。

考慮一下為什麼想要取消我們為一些原因建立的執行緒呢?比如在乙個有gui的介面,我們可能會使用乙個後台執行緒處理一些費事的操作,比如,查詢、準備列印檔案,介面通常會為使用者提供乙個停止按鈕來取消這些操作(在word中,可以取消要列印的檔案)。這個時候就需要執行緒取消操作了。

執行緒的取消

該函式傳送乙個取消請求到指定的執行緒中。

int pthread_cancel(pthread_t thread)

注意點:

1.當該函式傳送取消請求後,它立即返回,並不等待指定執行緒終止後才返回。

2.指定執行緒什麼時候返回,完全依賴於執行緒取消的狀態和型別

。3.當程序被取消後,pthread_join()函式返回pthread_canceled。

執行緒取消狀態

設定執行緒是否能被取消。

int pthread_setcancelstate(int state, int *oldstate)

注意點:

1.執行緒pthread_cancel_disable被設定後收到的取消請求都將被掛起(記住是被掛起,不是被丟失)。如果程式中要執行一段不能被打斷的操作時,設定該標誌。

2.pthread_cancel_enable,重新讓執行緒恢復到可以接受取消請求的狀態。該狀態是執行緒的預設狀態。

執行緒取消型別

int pthread_setcanceltype(int type, int *oldtype)

注意點:

1.執行緒的取消型別只有在pthread_cancel_enable標誌下才有意義。

2.pthread_cancel_asynchronous,非同步標誌。表示執行緒能在任意時刻被取消(該標誌很少使用,最後討論)。

3.pthread_cancel_deferred,推遲取消。取消請求要等到取消點(cancellation point)才能被處理。

取消點(cancellation point)

在推遲取消標誌設定後,取消請求只有在某些函式中才能被處理,這些函式就叫做取消點。

圖選自the linux programming inte***ce-chapter32

從上圖可推斷,大部分的取消點都是會讓執行緒阻塞的函式。當乙個執行緒到達乙個取消點時,系統決定是否有乙個未解決的針對目標執行緒的取消請求。如果目標執行緒從乙個取消點返回後,另外的執行緒針對目標執行緒呼叫了pthread_cancel(),就存在乙個未解決的取消。如果這一取消是未解決的,系統將很快開始呼叫清除函式(後面會提到),然後執行緒終止。

有時我們的執行緒中根本就沒有用到上面所列的取消點,那是否意味著執行緒就不能被取消?是的,不能被取消。所以,我們需要下面這個函式來解決這個問題。

執行緒取消測試

void pthread_testcancel(void)

再考慮下面這些場景:執行緒動態的分配了一些空間,或執行緒擁有某些鎖。但它在收到取消請求後自動的退出了。那分配的空間將會造成記憶體洩露,沒釋放的鎖將會讓其他執行緒一直被阻塞,這些都是很嚴重的問題。posix執行緒為了解決該問題,制定了下面的api。

執行緒清除

void pthread_cleanup_push(void (*routine)(void *), void *arg)

void pthread_cleanup_pop(int execute)

注意點:

1.pthread_cleanup_push()把清除函式加到棧(該棧專門為清除函式準備)中,pthread_cleanup_pop()把棧頂中的清除函式刪除。當執行緒被取消或它呼叫pthread_exit()退出時,系統從棧頂依次彈出清除函式,並執行。

2.當執行緒執行到底部時都未被取消,那麼呼叫pthread_cleanup_pop()來清除該處理函式(引數為0)。

3.當pthread_cleanup_pop()以非零值被呼叫時,就算執行緒沒被取消,清除處理函式也要被執行。

4.這兩個函式可以被設計為巨集,比如在pthread_cleanup_push中包含乙個。這樣在**中,必須要求這兩個函式成對的出現,必須在同乙個**塊中。

現在來討論一下非同步取消

推遲取消必要要在取消點才能取消執行緒,而非同步取消卻是直接終止執行緒,並不等待到某個取消點上。值得注意的是非同步取消也會呼叫清除函式,但是執行緒在被取消時,我們根本不知道執行緒是在什麼條件下被取消的(記憶體是否已經被分配,互斥量是否被鎖住了等),也就無法在清除函式中執行相對應的逆操作。

那非同步取消就一點用處都沒有了麼?當然有用,不然創造它幹什麼!對於乙個執行緊密計算迴圈的執行緒時,不斷地呼叫pthread_testcancel()是昂貴的,我們只能用非同步取消來完成取消。

當需要使用非同步取消時,有一些基本準則必須遵守:不能分配任何資源,不能要求任何互斥量,鎖等。

POSIX執行緒 4 執行緒的屬性

執行緒屬性有下面幾個方面 作用域 scope 決定執行緒優先順序範圍,程序內還是系統範圍。pthread scope process 程序 pthread scope system 系統 分離狀態 deteached state 分離執行緒在結束的時候不保留任何狀態資訊,釋放它所占有的資源,不能用j...

POSIX執行緒多執行緒例子

include include include include define num threads 6 void thread function void arg int main sleep 1 printf waiting for threads to finish.n for lots of...

執行緒操作 取消執行緒

include include include include 包含執行緒庫 void thread function void arg 定義執行緒函式原型 int main sleep 3 睡眠3秒 printf 取消執行緒.n res pthread cancel a thread 傳送取消執行...