死鎖是指在一組進程中的各個進程均占有不會釋放的資源,但因互相申請被其他進程所站用不會釋放的資源而處於的一種永久等待狀態。
死鎖的四個必要條件:
(1)互斥條件(Mutual exclusion):資源不能被共享,只能由一個進程使用。
(2)請求與保持條件(Hold and wait):已經得到資源的進程可以再次申請新的資源。
(3)非剝奪條件(No pre-emption):已經分配的資源不能從相應的進程中被強制地剝奪。
(4)循環等待條件(Circular wait):系統中若干進程組成環路,該環路中每個進程都在等待相鄰進程正占用的資源。
死鎖避免的方法
(1) 死鎖檢測和恢復(deadlock detection and recovery):
死鎖檢測(deadlock detection)即探查和識別死鎖的方法。這種策略並不采取任何動作來使死鎖不出現,而是系統事件觸發執行一個檢測算法。,也即在系統運行過程中,及時地探查和識別死鎖的存在,並識別出處於死鎖之中的進程和資源等。死鎖恢復(deadlock recovery)是指當檢測並識別出系統中出現處於死鎖之中的一組進程時,如何使系統回復到正常狀態並繼續執行下去。死鎖恢復常采用下述兩種方法。
1) 撤消進程即當發現死鎖時,就撤消(夭折)一些處於死鎖狀態的進程,並收回它的占用的資源,以解除死鎖,使其它進程能繼續運行,或者在提供檢查點(checkpoint)信息情況下回退(rolled back)到一個較早的狀態。這里有一個開銷問題,即撤消哪個(些)進程比較“划算”。
2) 掛起進程即當發現死鎖時,掛起一些進程,搶占它們占用的資源,使得處於死鎖之中的其它進程繼續執行。待以后條件滿足后,再恢復被掛起的進程。
常利用資源分配圖、進程等待圖來協助這種檢測。
(2) 死鎖預防(deadlock prevention):
死鎖預防(deadlock prevention)是在系統運行之前,事先考慮防止死鎖發生的對策,即在最初設計各種資源調度算法時,就沒法防止在系統運行過程中可能產生的死鎖。
Coffmman 等人[1971]曾提出進程在利用可重用性資源時產生死鎖的四個必要條件:
1) 互斥使用(mutual exclusion):系統中存在一次只能給一個進程使用的資源。
2) 占用並等待(resource holding and waiting):系統中存在這樣的進程,它(們)已占有部分資源並等待得到另外的資源,而這些資源又被其它進程所占用還未釋放。
3) 非搶占分配(nonpreemption):資源在占有它的進程自願交出之前,不可被其它進程所強行占用。
4) 部分地分配(partial allocation)或循環等待(circular waiting):存在一個兩個或都個進程的循環鏈,鏈中每一個進程等待被鏈中下一個進程占有的資源。即在一定條件下,若干進程進入了相互無休止地等待所需資源的狀態。
所有這四個必要條件都應該在死鎖時出現。
Havender[1968]提出了若干死鎖預防方法。他認為,只要設法破壞產生死鎖的任一必要條件,死鎖就不會發生。為此,可采用如下策略:
1) 每個進程必須一次性地請求它所需要的所有資源。若系統無法滿足這一要求,則它不能執行。這是一種預分資源方法,它破壞了產生死鎖的第三個必要條件。
2) 一個已占有資源的進程若要再申請新資源,它必須先釋放已占資源。若隨后它還需要它們,則需要重新提出申請。換言之,一個進程在使用某資源過程中可以放棄該資源,從而破壞了產生死鎖的第二個必要條件。
3) 將系統中所有資源順序編號,規定進程只能依次申請資源,這就是說,一個進程只有在前面的申請滿足后,才能提出對其后面序號的資源的請求。這是一種有序使用資源法,它破壞了產生死鎖的第四個必要條件。
(3) 死鎖避免(deadlock avoidence):
死鎖避免(deadlock avoidence)是在系統運行過程中注意避免死鎖的發生。這就要求每當申請一個資源時,系統都應根據一定的算法判斷是否認可這次申請,使得在今后一段時間內系統不會出現死鎖。這面方最著名的算法首推Dijkstra[1965]提出的銀行家(banker)算法。