死結

死結預防(deadlock prevention)

回想死結需要四種材料同時俱全,就像火需要燃料、熱、氧氣。最簡單的心態是:只要保證有一種材料永遠不會出現,死結就在結構上不可能發生——不是不太可能,而是不可能。這就是死結預防:把系統設計成四個必要條件中至少有一個永遠無法成立,於是死結從構造上就無法形成。不需執行期檢查、不需偵測、不需復原——那個壞狀態根本到不了。

具體而言,預防會攻擊四個條件之一。在可能處否定互斥(讓資源可共享,或用排存器,使行程不直接相爭——不過有些資源本質上不可共享)。否定持有並等待,做法是要求一次取得全部:行程必須在開始前請求它將需要的一切,或必須在請求更多之前先釋放它所持有的一切。否定不可剝奪,做法是允許系統強行收回被持有的資源(只對狀態能儲存並還原的資源才安全)。否定循環等待,做法是對資源類型施加全序、要求依遞增順序取得——這是四者中最實用的,在程式碼中實現為鎖定排序。

預防穩健、且不需事先知道未來的請求,但坦白說它很保守:它禁止整類行為模式,往往傷害資源使用率與並行度。一次取得全部會讓行程囤積尚未使用的資源,並可能餓死需要許多熱門資源的行程。嚴格排序在自然的程式結構偏好不同取鎖順序時也很彆扭。這就是核心取捨:預防安全、易於推理,卻以悲觀為代價換取這份安全——這也是為何許多系統寧可採用避免、偵測,或乾脆無視這個問題。

鎖定排序預防:把鎖全域編號(mutex_1、mutex_2、mutex_3),並要求每個執行緒只能依索引遞增的順序取得。持有 mutex_2 的執行緒可以再取 mutex_3,但絕不能取 mutex_1,於是循環等待永遠無法形成。

對取鎖施加全序,直接否定循環等待條件。

預防無需執行期檢查即保證安全,但很悲觀:它禁止看似合法的行為,並傾向降低使用率與並行度。避免是限制較少的近親,它利用未來需求的資訊。

又称
preventing deadlock預防死結