經典同步問題與並行程式設計
寫者飢餓(writer starvation)
飢餓是指一個執行緒已就緒可執行、正等待某資源,但系統發放該資源的方式一再略過它,於是它無限期等下去。寫者飢餓是讀者-寫者問題裡那個著名的具體案例:想寫的執行緒被永遠延後,因為讀者不斷插隊到它前面。想像尖峰時刻某人想從匝道併入高速公路——若政策是「已在高速公路上的車永遠不必禮讓」,而高速公路又從不淨空,那輛要併入的車可能整天卡在那裡。它不是被臭蟲擋住,而是被不公平的政策擋住。
它直接源自偏向讀者。在那個解法裡,只要目前沒有寫者正在寫,讀者就能進入——而關鍵在於,它不檢查是否有寫者正在等待。於是若讀取彼此重疊(一位讀者還在裡面時下一位就到了),讀者計數永不降到零,寫者鎖永不釋放,等待的寫者永遠輪不到。重要的是,這不是死結:讀者們進展順利、工作照常完成,卡住的只有寫者。這個區別很要緊——死結凍住所有人,飢餓則單獨挑出一個受害者。
解法全都歸結為引入公平。偏向寫者會在有寫者等待時,阻止任何新讀者進入,從而保證寫者終究能跑(但接著可能改成餓死讀者)。公平或先進先出的方案大致按到達順序服務請求,為每個人的等待設下上限。超出這道謎題之外、反覆出現的作業系統教訓是:光有互斥還不夠——正確的並行設計還必須承諾有限等待(bounded waiting),亦即保證沒有任何執行緒會永遠等下去。
讀者 R1、R2、R3……在前一位讀者仍在閱讀時陸續到來,使計數永不歸零。從一開始就就緒的寫者 W,眼看每位讀者來了又走,卻始終拿不到鎖。
這是飢餓,不是死結:讀者全部完成,唯獨寫者被無限期延後。
別把飢餓和死結搞混。死結中沒有人能前進;飢餓中系統整體仍有進展,只是某個倒楣的執行緒被持續略過。老化(aging,逐漸提高等待者的優先權)是常見的解法。
又称
另见