古詩詞大全網 - 成語故事 - 什麽是死鎖 死鎖的處理方法

什麽是死鎖 死鎖的處理方法

在並發程序設計中,死鎖 (deadlock) 是壹種十分常見的邏輯錯誤。通過采用正確的編程方式,死鎖的發生不難避免。

死鎖的四個必要條件

在計算機專業的本科教材中,通常都會介紹死鎖的四個必要條件。這四個條件缺壹不可,或者說只要破壞了其中任何壹個條件,死鎖就不可能發生。我們來復習壹下,這四個條件是:

?互斥(Mutual exclusion):存在這樣壹種資源,它在某個時刻只能被分配給壹個執行緒(也稱為線程)使用;

持有(Hold and wait):當請求的資源已被占用從而導致執行緒阻塞時,資源占用者不但無需釋放該資源,而且還可以繼續請求更多資源;

不可剝奪(No preemption):執行緒獲得到的互斥資源不可被強行剝奪,換句話說,只有資源占用者自己才能釋放資源;

環形等待(Circular wait):若幹執行緒以不同的次序獲取互斥資源,從而形成環形等待的局面,想象在由多個執行緒組成的環形鏈中,每個執行緒都在等待下壹個執行緒釋放它持有的資源。

解除死鎖的必要條件

不難看出,在死鎖的四個必要條件中,第二、三和四項條件比較容易消除。通過引入事務機制,往往可以消除第二、三兩項條件,方法是將所有上鎖操作均作為事務對待,壹旦開始上鎖,即確保全部操作均可回退,同時通過鎖管理器檢測死鎖,並剝奪資源(回退事務)。這種做法有時會造成較大開銷,而且也需要對上鎖模式進行較多改動。

消除第四項條件是比較容易且代價較低的辦法。具體來說這種方法約定:上鎖的順序必須壹致。具體來說,我們人為地給鎖指定壹種類似“水位”的方向性屬性。無論已持有任何鎖,該執行緒所有的上鎖操作,必須按照壹致的先後順序從低到高(或從高到低)進行,且在壹個系統中,只允許使用壹種先後次序。

請註意,放鎖的順序並不會導致死鎖。也就是說,盡管按照 鎖A, 鎖B, 放A, 放B 這樣的順序來進行鎖操作看上去有些怪異,但是只要大家都按先A後B的順序上鎖,便不會導致死鎖。

舉例

假如有三個對象A、B、C,我們人為約定它們的鎖序是: A 先於 B 先於 C。舉例說來,下列鎖序均為合法:

? 鎖C,放C

鎖B,放B

鎖B,鎖C,放B,放C

鎖B,鎖C,放C,放B

鎖A,放A

鎖A,鎖C,放A,放C

鎖A,鎖C,放C,放A

鎖A,鎖B,放A,放B

鎖A,鎖B,放B,放A

鎖A,鎖B,鎖C,放A,放B,放C

鎖A,鎖B,鎖C,放C,放B,放A

而在上面定義的系統中,可能導致發生死鎖典型上鎖序列包括:

? 鎖B,鎖A,鎖C,放C,放A,放B

(因為先B後A的上鎖順序違反了鎖序約定,如果另壹執行緒同時按照先A後B的順序上鎖,則可能由於執行緒甲獲得了B,執行緒乙獲得了A,而導致雙方同時等待對方釋放所持有的鎖,從而形成死鎖局面;解法是將操作序列中增加適當的鎖操作,即改為鎖B,放B,鎖A,鎖B,鎖C,放C,放A,放B)

或者說,只要拿鎖的時候不出現逆序(例如拿著C的時候試圖抓B或A,或者拿著B的時候試圖抓A),並出現潛在逆序的時候先放掉“小”鎖再抓大的,就壹定不造成死鎖了。