我正在編寫一個多線程程序,我有這個問題: 假設,在主線程中執行時,我想終止所有 子線程。我不能給他們發送終止信號,因爲我希望他們首先釋放動態分配的內存。我可以在每個被執行的線程函數中定義一個特定的信號處理函數 函數,而函數又將調用 一個清理函數,我會這樣寫?如果不是我怎麼能實現我的目標?線程中的信號處理程序
感謝, 尼科斯
我正在編寫一個多線程程序,我有這個問題: 假設,在主線程中執行時,我想終止所有 子線程。我不能給他們發送終止信號,因爲我希望他們首先釋放動態分配的內存。我可以在每個被執行的線程函數中定義一個特定的信號處理函數 函數,而函數又將調用 一個清理函數,我會這樣寫?如果不是我怎麼能實現我的目標?線程中的信號處理程序
感謝, 尼科斯
看看man頁pthread_cancel
:
在請求取消時採取行動,出現了 線以下(按順序):
1. Cancellation clean-up handlers are popped (in the reverse of the order in
which they were pushed) and called. (See pthread_cleanup_push(3).)
2. Thread-specific data destructors are called, in an unspecified order. (See
pthread_key_create(3).)
3. The thread is terminated. (See pthread_exit(3).)
所以你可以使用主要的pthread_cancel
,前提是您已經使用上述功能正確註冊了清理處理程序。
(請閱讀手冊頁完全雖然,它有很多重要的信息。)
編輯:(從評論)如果您打算使用PTHREAD_CANCEL_DEFERRED
,需要在某個地方插入一個取消點你代碼,然後使用pthread_testcancel
。該功能檢查是否要求取消。如果是這種情況,則取消服務(即該呼叫永不返回)。否則它不起作用。
最穩健的策略需要從子線程合作:你設置一個標誌,該線程定期檢查,當設置了標誌,他們正在使用免費的一切資源,然後終止。
'定期檢查一個變量'當然是'使用一個pthread條件變量'的速記' - **'
這是不可能的,如果線程可能被阻塞長期或永久阻塞/睡覺系統調用。這就是爲什麼取消存在。 – 2011-05-19 11:28:25
取消(馬太福的答案)是正確的,規範的,但如果你想有一個不同的方法,你可以安裝使用sigaction
無操作信號處理程序沒有SA_RESTART
標誌和使用pthread_kill
你才能選擇任何信號數中斷(EINTR
)無論線程可能被阻塞。與此相結合,艾克斯的答案起作用。
這是一個很好的解決方案。我自己使用它,設計出來整齊。 – Jay 2011-05-19 11:59:12
感謝您的回答!我正在考慮使用pthread_cleanup_push和相應的退出處理函數來釋放所有內容。如果我設置PTHREAD_CANCEL_DEFERRED是否有效,有一個睡眠(0)作爲取消點,所以我不會有任何開銷? – nikos 2011-05-19 12:52:58
@nikos:這不是最好的方法。使用['pthread_testcancel'](http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_testcancel.3.html),這正是它的目的。睡眠可以通過信號來實現,並且睡眠不保證不睡眠 - 唯一的保證是睡眠時間至少爲0秒。 – Mat 2011-05-19 12:59:29