The Little Book of Semaphores 訊號量小書 第四章 經典同步問題 4.5 吸菸者問題
第四章 經典同步問題
4.5 吸菸者問題
吸菸者問題問題最初由Suhas Patil [8]提出,他聲稱用訊號量無法解決。 這種說法帶有一定的條件,但無論如何,問題是有趣且具有挑戰性的。
涉及四個執行緒:代理人和三個吸菸者。 吸菸者永遠地迴圈,首先等待配料,然後製作和吸菸。配料的成分是菸草,紙和火柴。
我們假設代理商擁有無限供應的所有三種成分,每個吸菸者都有無限供應的其中一種成分; 也就是說,一個吸菸者有火柴,另一個有紙,第三個有菸草。
代理商反覆隨機地選擇兩種不同的成分,並使其可供吸菸者使用。根據選擇的成分,具有補充成分(剩下那種成分)的吸菸者應該拿走這兩種資源並繼續處理(製作和抽菸)。
例如,如果代理商拿出菸草和紙張,那麼擁有火柴的吸菸者應該拿起兩種成分,製作香菸,然後發出訊號給代理商。
為了解釋這個前提,代理表示分配資源的作業系統,而吸菸者表示需要資源的應用程式。 問題是要確保:如果資源可用,允許再多執行一個應用程式,那麼應該喚醒這些應用程式。 相反,如果應用程式無法繼續,我們希望避免喚醒它。
基於這個前提,這個問題有三個版本經常出現在教科書中:
不可能版本:Patil的版本對解決方案施加了限制。首先,您不能修改代理程式碼。 如果代理表示作業系統,則假設您不希望每次新應用程式出現時都修改它,這是有意義的。 第二個限制是您不能使用條件語句或訊號量陣列。 有了這些限制,問題就無法解決,但正如Parnas所指出的那樣,第二個限制是非常人為的[7]。 由於這些限制,許多問題變得無法解決。
有趣的版本:此版本保留了第一個限制 - 您無法更改代理程式碼 - 但它會丟棄其他程式碼。
平凡的版本:在一些教科書中,問題指出代理人應該根據可用的成分發訊號通知下一個應該接下來的吸菸者。 這個版本的問題是無趣的,因為它使整個前提,成分和香菸,都無關緊要。 此外,實際上,要求代理知道執行緒以及它們正在等待的內容可能不是一個好主意。 最後,這個版本的問題太容易了。
當然,我們將專注於有趣的版本。 要完成問題陳述,我們需要指定代理程式碼。 代理使用以下訊號量:
代理實際上由三個併發執行緒組成,代理A,代理B和代理C.每個代理都在agentSem上等待; 每當agentSem發出訊號時,其中一個代理就會通過發出兩個訊號量的訊號來喚醒並提供成分。
這個問題很難,因為自然解決方案不起作用。 很容易寫出這樣的東西:
這個解決方案有什麼問題?
4.5.1 死鎖-6#
先前解決方案的問題是存在死鎖的可能性。 想象一下,代理商推出了菸草和紙張。 由於有火柴的吸菸者正在等待菸草,因此可能會被解除阻止。 但是有菸草的吸菸者正在等待紙張,因此有可能(甚至可能)它也會被解除阻止。 然後第一個執行緒將在紙張上阻塞,第二個執行緒將在火柴上阻塞。死鎖!
4.5.2 吸菸者問題提示
Parnas提出的解決方案使用三個稱為“販毒者(pushers)”的輔助執行緒,響應來自代理的訊號,跟蹤可用的成分,並給相應的吸菸者傳送訊號。
附加變數和訊號量是
布林變量表示該成分是否在桌子上。販毒者使用菸草來向吸菸者發出菸草訊號,同樣也使用其他訊號量。
4.5.3 吸菸者問題解決方案
以下是其中一個販毒者的程式碼:
未完待續。