死結偵測(deadlock detection)
有些系統不靠禁止快速駕駛來防止事故(預防),也不對每趟行程事先審核(避免),而是採取放鬆的觀點:讓車自由行駛,但備好一輛拖吊車,並定期檢查有沒有人撞車、把交通凍住了。死結偵測就是這種做法——作業系統允許死結發生,然後不時跑一個演算法,找出是否真有一組行程陷入死結,好把它清理掉。
它怎麼找到死結?在單一實例的情形,作業系統建立一張等待圖(行程當節點,從 Pi 到 Pj 的邊表示 Pi 在等 Pj 所持有的資源),並尋找環;有環就是死結。對多實例,光有環不夠,於是用更仔細的演算法——本質上就是把銀行家的安全檢查跑在「當前」狀態上、且不需要 Max:若某行程未完成的請求能由目前可用的實例滿足,就標記它「可完成」,假裝它完成並釋放,然後重複;任何永遠無法被標記為可完成的行程都是某個死結的一部分。作業系統可選擇跑這個檢查的頻率:每次請求都跑(昂貴,能即時找到死結),或定期/只在 CPU 使用率下降且許多行程被阻塞時才跑(較便宜,但死結可能一陣子未被察覺)。
偵測與復原成對——找到死結若不接著靠終止或回復行程把它打斷,就毫無用處。誠實的取捨在於時機與成本。不停地跑偵測精確,卻燒 CPU;很少跑便宜,卻讓死結的行程(及它們凍住的資源)閒置更久,也讓復原更難,因為可能損失更多工作。當死結罕見到不值得一直付預防/避免的額外成本、卻又常見到完全無視並不可接受時,偵測就是合理之選。
單一實例偵測:建立等待圖並搜尋環。若出現 P1 -> P2 -> P3 -> P1,這三者就陷入死結。多實例偵測:反覆把任何請求能塞進可用量的行程標記為完成並回收其資源;最後仍未被標記的就是死結。
單一實例偵測尋找環;多實例偵測執行一輪「完成並回收」的掃描。
偵測只負責找出死結;沒有復原步驟它什麼也辦不到。跑得勤精確但昂貴;跑得少便宜卻讓死結拖延、浪費資源。