初看這個主題時,覺得實在簡單。在我印象中,執行緒取消的實現通常是宣告乙個全域性變數來代表取消標誌,乙個執行緒在最開始的大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 傳送取消執行...