在編寫多執行緒**時,經常面臨執行緒安全退出的問題。
一般情況下,選擇檢查標誌位的方式:
這個標誌位需要主線程(或其他執行緒)設定,設定後,主線程呼叫pthread_join介面進入休眠(介面引數指定了等待的執行緒控制指標),子執行緒退出後,主線程會接收到系統的訊號,從休眠中恢復,這個時候就可以去做相關的資源清除動作。
這個方法可以保證子執行緒完全退出,主線程再去做相關的資源清除操作
但是某些應用中,或許會發生下面情況:
子執行緒阻塞在某個操作無法被喚醒,即使主線程設定了標誌位,由於子執行緒進入了休眠無法醒過來,也沒有辦法去檢查標誌位,這個時候呼叫pthread_join進入休眠的主線程等待不到子執行緒退出的訊號,也會一直休眠,系統進入死鎖。
為了更安全地使執行緒退出,主線程通過pthread_cancel函式來請求取消同一程序中的其他執行緒,再呼叫pthread_join等待指定執行緒退出。使用pthread_cancel介面,需要了解linux下執行緒的兩個屬性,可取消狀態和可取消型別,以及取消點的概念。
可取消狀態:包括pthread_cancel_enable和pthread_cancel_disable。當執行緒處於pthread_cancel_enable,收到cancel請求會使該執行緒退出執行;反之,若處於pthread_cancel_disable,收到的cancel請求將處於未決狀態,執行緒不會退出。執行緒啟動時的預設可取消狀態為pthread_cancel_enable,可以通過介面pthread_setcancelstate改變可取消狀態的屬性。
可取消型別:包括pthread_cancel_deferred和pthread_cancel_asynchronous。當處於pthread_cancel_deferred,執行緒在收到cancel請求後,需要執行到取消點才能退出執行;如果處於pthread_cancel_asynchronous,可以在任意時間取消,只要收到cancel請求即可馬上退出。執行緒啟動時預設可取消型別為pthread_cancel_deferred,可通過pthread_setcanceltype修改可取消型別。
取消點:執行緒檢查是否被取消並按照請求進行動作的乙個位置。
採用pthread_cancel_deferred取消方式是因為執行緒可能在獲取臨界資源後(如獲取鎖),未釋放資源前收到退出訊號,如果使用pthread_cancel_ asynchronous的方式,無論執行緒執行到哪個位置,都會馬上退出,而占有的資源卻得不到釋放。
採用pthread_cancel_deferred取消方式,執行緒需要執行到取消點才退出,而主線程在呼叫pthread_cancel後,不能馬上進行執行緒資源釋放,必須呼叫pthread_join進入休眠,直至等待指定執行緒退出。
使用pthread_cancel_deferred方式並不能完全避免這個問題,因為無法保證在獲取臨界資源後(比如lock操作)不會進行可以作為取消點的操作(如進行sleep),此時主線程如果對該執行緒傳送cancel訊號,執行緒將會在不釋放鎖的情況下直接結束執行,即還是會出現在釋放資源前線程就退出的問題。
為了避免上述情況,不僅需要設定可取消型別,還需要設定可取消狀態。將獲取臨界資源-釋放臨界資源之間的**塊都設定成pthread_cancel_disable狀態,其餘的**塊都設定成pthread_cancel_enable狀態,確保執行緒在安全的地方退出。如果在可以安全退出的**塊不存在取消點系統呼叫,可以呼叫pthread_testcancel函式自己新增取消點。
void
*subthread
(void*)
void
*mainthread
(void*)
無論使用哪種方式,核心點就是要保證執行緒退出的時候不會獲取了某些臨界資源而無法釋放posix.1定義的取消點見下:
注意:當主線程呼叫pthread_cancel介面後,只是將取消請求傳送給指定執行緒,
對介面的成功呼叫不能保證指定執行緒已經退出,需要呼叫pthread_join等待指定執行緒完全退出,再進行相關資源的釋放。
概念參考:
pthread_setcanceltype 執行緒取消
Linux執行緒退出方式總結
這個標誌位需要主線程 或其他執行緒 設定,設定後,主線程呼叫pthread join介面進入休眠 介面引數指定了等待的執行緒控制指標 子執行緒退出後,主線程會接收到系統的訊號,從休眠中恢復,這個時候就可以去做相關的資源清除動作。這個方法可以保證子執行緒完全退出,主線程再去做相關的資源清除操作 時序圖...
Linux執行緒退出方式總結 推薦
在編寫多執行緒 時,經常面臨執行緒安全退出的問題。一般情況下,選擇檢查標誌位的方式 程的while迴圈中,執行完例程後,都對標誌位進行檢查,如果標誌位指示繼續執行則再次執行例程,如果標誌位設定為退出狀態,則跳出迴圈,結束執行緒的vhfby執行。這個標誌位需要主線程 或其他執行緒 設定,設定後,主線程...
LINUX程序和執行緒 通訊以及退出方式
可能涉及概念 程序 系統進行資源分配和排程的基本單位 執行緒 程式執行流的最小單元,輕量級程序 單工 類似高速公路中的單車道 只往乙個方向,收或者發 半雙工 類似單通道的普通馬路,一時間只允許一輛車 和單工比起來可以切換方向 全雙工 如同高速公路,每個裝置都可以收發 通訊方式 程序間通訊 7種 管道...