1. 程式人生 > >The Little Book of Semaphores 訊號量小書 第五章 稍欠經典的同步問題 5.7 過河問題

The Little Book of Semaphores 訊號量小書 第五章 稍欠經典的同步問題 5.7 過河問題

第五章 稍欠經典的同步問題

5.7 過河問題

這個問題來自於加州大學伯克利分校的安東尼·約瑟夫寫的問題集,但我不知道他是不是原作者。 它類似於H2O問題,因為它是一種特殊的屏障,只允許執行緒以某種組合通過。

 在華盛頓州雷德蒙德附近,有一艘划艇,Linux黑客和微軟員工(農奴)都用它來過河。渡船能容納四人,不會離岸。為了保證乘客的安全,不允許把一個黑客加三個農奴或者一個農奴加三個黑客放在船上。其他任何組合都是安全的。

當每個執行緒登上船時,它應該呼叫一個叫做board的函式。 您必須保證船上的所有四個執行緒都要在下一次船載的任何執行緒之前呼叫board。

在所有四個執行緒都呼叫了board之後,其中只有一個要呼叫一個名為rowBoat的函式,表明該執行緒將拿槳划船。 是哪一個執行緒呼叫該函式並不重要,只要有一個呼叫了即可。

不要擔心旅行的方向。 假設我們只對其中一個方向的交通感興趣。

5.7.1 過河提示

以下是我在解決方案中使用的變數:

hackers和serfs計算等待登船的黑客和農奴的數量。 由於它們都受互斥鎖保護,因此我們可以檢查兩個變數的狀況,而不必擔心不合時宜的更新。 這是記分牌的另一個例子。

hackerQueue和serfQueue允許我們控制通過的黑客和農奴的數量。 屏障確保所有四個執行緒在隊長呼叫rowBoat之前呼叫了board。

isCaptain是一個區域性變數,指示哪個執行緒應該呼叫row。

5.7.2 過河方案

這個解決方案的基本思想是每個到達的執行緒更新一個計數器,然後檢查它是否構成完整的互補,或者作為其種類的第四個,或者完成一個混合組。

我將介紹黑客的程式碼; 農奴的程式碼是對稱的(當然,除了它大1000倍,充滿了bug,包含一個嵌入式Web瀏覽器):

當每個執行緒通過互斥部分時,它會檢查是否有完整的船員準備登船。 如果是,它會向相應的執行緒發出訊號,宣告自己是隊長,並持有互斥鎖,以便阻止其他的額外執行緒,直到船啟航。

屏障記錄了已登船的執行緒數。 當最後一個執行緒到達時,所有執行緒都會繼續執行。 船長呼叫row,然後(最後)釋放互斥鎖。