2010-03-26 63 views
2

任何創造性的想法,以避免產出或睡眠死鎖與合作/非搶先多任務而不做O/S Thread.Sleep(10)?通常,良率或睡眠呼叫將回調到調度程序中以運行其他任務。但是這有時會產生僵局。合作/非搶先式線程避免死鎖?

一些背景資料:

此應用對速度和巨大需求,到目前爲止,相對於同行業其他系統它的速度極快。其中一種速度技術是協作/非搶先式線程,而不是從O/S線程切換上下文的開銷。

高層次設計優先級管理器,根據優先級和處理時間調用任務。每個任務執行一次工作「迭代」,並返回以再次在優先隊列中等待。

與非搶佔式線程棘手的是,當你想要一個特定的任務停止在工作中,繼續之前從不同的任務等待其它一些事件做什麼。

在這種情況下,我們有3個任務,A B和C,其中A是必須同步B和C首先活性的控制器,A開始B和C.則B產生所以C被調用。當C收益率,A看到他們都是不活躍的,決定B是運行的時間,但沒有C的時間。 B井現在停留在一個叫做C的產量上,所以它永遠不會運行。

+0

有趣的問題。標記了這個C#,因爲你的答案似乎表明那是你正在使用的語言。 – 2015-10-17 18:08:00

回答

0

好吧,如果實現了C#語言支持真正的「延續」到unwide堆棧,並繼續在那裏後離開這個理想的解決辦法是。

在沒有我們被允許在這種情況下,任務到「isInterrupted」標誌設置爲true和回報使我們自己的臨時替換 - 從而平倉堆棧。

然後當調度程序想要重新安排處理時間這項任務,它會看到isInterrupted並跳過已經做了正確的跳轉到中斷位置使用簡單的if語句的處理。

此致, 韋恩

1

我認爲這可能是處理這種最徹底的方法是分離屈服(線程決勝盤已經處理了足夠的一段時間)阻塞(等待特定的事件)。這樣可以讓花費時間的線程相對容易,但避免嘗試運行被阻塞的線程造成死鎖。一般來說,你想對什麼線程在其他線程上阻塞進行拓撲排序,這樣你就可以給其他人等待的線程留出時間。這應該給DAG - 圖中的任何循環都表示出現死鎖。

+0

好的,好點。更多信息:我們已經這樣做了。你所稱的「屈服」,我們通過一個任務來處理,只是做一次返回,這樣堆棧就會退回到調度器。這意味着在這個問題討論中的所有收益和睡眠都是阻塞的。像這樣:while(!xevent)Yield(); 我們已經處理了DAG並解決了所有其他情況。但是,上面問題中的問題,如果你更仔細地研究它,那不是那樣解決的。 B和C之間沒有依賴關係。它只是它們必須同步。所以他們必須暫停並等待接下來將要運行的通知。 – Wayne 2010-03-26 07:49:49

+0

這裏的根本問題是每個任務都在等待時綁定堆棧。一個很麻煩的解決方案是將B和C分成兩個任務。 因此B變成B1和B2。這樣B1和B2可以通過彼此來回切換狀態來運行。如果一個塊需要在B1的末尾,所以它可以在禁用B2之後退出任務,因此B2將不會開始運行,直到被A重新激活。 這樣在兩種情況下都會釋放堆棧。 把可愛的代碼分成這樣的片段很難看。但如果沒有更好的想法。 – Wayne 2010-03-26 07:54:13

+0

也許我只是睡不着覺,但我仍然不太在意這個問題。哪個線程具有'while(!xevent)Yield();',並且你期望設置'xevent'?稍微改變一下規則,就會出現一種相當不同的可能性:使用協作式多任務來減少開銷,但是使用看門狗定時器,只有在死鎖情況下才會搶佔*。 – 2010-03-26 08:31:59