2011-08-03 43 views
0

此問題源於Breaking a condition variable deadlock。許多線程可能正在等待一個條件變量,我只需要發信號通知一個特定的線程,如線程1並殺死它,因爲它是一個死鎖場景的參與者。有沒有一種方法可以在很多方面發出一個單獨的線索。在等待條件變量的許多信號中發送特定線程

會一些幫助是gratefull

感謝

的編輯;尊重尼莫的評論。我明白這是一個壞主意。但是,有沒有辦法做到這一點

+4

由於概率非常接近1,因此您的設計存在缺陷。你幾乎肯定不希望「檢測到死鎖並殺死參與其中的線程之一」。你想修復你的基本設計,以防止發生死鎖...... – Nemo

+0

@Nemo ...我同意你的看法。但是,在我們的特殊情況下,我們選擇檢測並解決死鎖而不是避免死鎖,因爲死鎖發生的可能性非常罕見。 –

+1

對不起@Juggler,但我不買這種哲學。這是軟件。沒有「極其罕見」的東西。只有「從不」和「越野車」。或者尤達會說,沒有嘗試。 – Nemo

回答

1

您可以使用延期取消點。在你的線程中,使用pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldstate);(這是默認的,但從不傷害是明確的);然後通過pthread_setcancelstate禁用取消,除了超出條件變量等待您希望取消。請確保您使用pthread_cleanup_push來設置取消清理處理程序;這與RAII不會很好地配合。

現在你可以只是pthread_cancel你的線程。按照註冊的相反順序執行取消清理處理程序,調用TLS數據析構函數,並且線程退出(不從條件變量wait中返回)。

當然,這是一個相當醜陋的設計。理想情況下,你應該避免死鎖;如果這是不可能的,如果是我,我會安排一次只有一個線程阻塞單個cvar,並基於這些cvars構建更高級別(顯式服務器列表)構造以處理多個服務員,同時仍然允許線程單獨尋址。

+0

您能詳細解釋一下嗎?在取消和等待條件變量之間是否沒有根本的競爭條件?也就是說,你持有一個互斥量,啓用取消,然後嘗試等待cond var ...但是在此期間有人決定你僵持並且在你持有互斥鎖的時候核武你? – Nemo

+0

@Nemo,從pthread_cond_wait手冊頁:「條件等待(無論是否定時)是取消點。當一個線程的可取消使能狀態設置爲PTHREAD_CANCEL_DEFERRED時,在條件等待期間作用於取消請求的副作用是在調用第一個取消清除處理程序之前重新獲取互斥(實際上)。「因此,您的清理處理程序必須釋放互斥鎖。 – bdonlan

0

只需編寫代碼即可完成您所需的任務。沒有捷徑,因爲條件變量不提供這種行爲。所以寫下吧。這沒有什麼困難。例如,您可以設置一個特殊標誌,喚醒所有線程在條件變量上被阻塞,然後對線程進行編碼以檢查標誌以確定是否應該返回到睡眠狀態。