問題
我想在 GUI (Qt 5.15.2) 的一個特殊事件上停止整個程式行程,除了 GUI 執行緒,并顯示一個錯誤訊息對話框并終止程式。
1)獲取所有正在運行的執行緒的問題
我需要將所有其他正在運行的執行緒置于睡眠狀態,然后才能導致諸如分段錯誤之類的問題。使用 POSIX 執行緒 API 和 MS-Windows API,我們有一個適當的 API 來獲取所有正在運行的執行緒的串列。但我沒有從 STL 中找到類似的。是否有任何跨平臺 API(甚至來自 Qt 或 Boost 等第三方庫)?或者我必須使用特定于平臺的 API 來實作?
2) 將所有正在運行的執行緒置于睡眠狀態的問題
獲得正在運行的執行緒后,我怎么能在它們處于某種阻塞操作中間時讓它們進入睡眠狀態?這是可能的?
uj5u.com熱心網友回復:
一般來說,您所要求的東西是不可能的,至少在沒有保留您自己的活動執行緒串列并與它們合作以實作該結果的情況下是不可能的。
例如,如果您的主/GUI 執行緒保留其自己的活動執行緒串列(它在生成執行緒時附加到該串列,并在它加入退出執行緒時從中洗掉),它也可以維護一個QMutex物件串列(每個執行緒一個),并“暫停所有執行緒”,它可以獲取QMutex串列中的每個執行緒。這本身根本不會影響執行緒,但是如果您將代碼添加到每個執行緒以定期獲取然后立即釋放它的QMutex,那么下次執行緒嘗試獲取QMutex它時它將阻塞在獲取函式中,直到主執行緒決定QMutex再次釋放。
也就是說,我不認為讓所有正在運行的執行緒休眠是解決問題的正確方法。如果您的問題是當您嘗試退出程式時執行緒偶爾會崩潰,則該問題的正確解決方案是執行受控關閉:讓您的主執行緒要求所有子執行緒離開(通過std::atomic<bool>或pipe()或socketpair()或條件-變數或任何其他方便的機制),然后join()在退出之前呼叫每個子執行緒。這樣,當主執行緒最終退出時,可以保證不再有子執行緒在運行,因此在主執行緒清理資源和嘗試仍然使用它們的子執行緒之間不存在競爭條件。
如果您的子執行緒卡在阻塞呼叫中,這可能是一個問題,因為子執行緒直到阻塞呼叫回傳后才能退出,并且主執行緒join()在所有子執行緒都完成之前無法完成所有呼叫執行緒已經退出。處理該問題的一種方法是在阻塞呼叫上設定超時,以便子執行緒能夠定期解除阻塞并查看它們是否需要退出;不過,這有點難看,所以在我的程式中,我嘗試只使用非阻塞 I/O(例如,讓子執行緒只在select()or內部阻塞poll(),當主執行緒希望它們離開時,它會發送一個位元組apipe()子執行緒正在選擇讀取就緒,以通知子執行緒是時候盡快退出了)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/354210.html
