死鎖
死鎖是指在併發系統中,兩個或多個程序因為互相等待對方釋放資源而無法繼續執行的狀態。
死鎖發生的條件通常包括以下四個條件:
- 互斥條件(Mutual Exclusion):
至少有一個資源
被標記為只能被一個程序
佔用,即一次只能有一個程序使用該資源。 - 請求與保持條件(Hold and Wait):一個程序在
持有至少一個資源
的同時,又請求其他程序
佔用的資源。 - 不可剝奪條件(No Preemption):已經分配給一個程序的資源
不能被強制性地剝奪
,只能由持有該資源的程序主動釋放 - 迴圈等待條件(Circular Wait):存在一個程序資源的迴圈鏈,每個程序都在等待下一個程序所佔用的資源。
當這四個條件同時滿足時,就可能發生死鎖。為了避免死鎖的發生,可以採取一些策略,如資源預分配、避免迴圈等待、引入資源剝奪等。
如何應對死鎖
死鎖預防
前面我們提到,產生死鎖的四個必要條件是:互斥條件、持有並等待條件、不可剝奪條件、環路等待條件。
那麼避免死鎖問題就只需要破環其中一個條件就可以,最常見的並且可行的就是使用資源有序分配法,來破環環路等待條件。
那什麼是資源有序分配法呢?
執行緒 A 和 執行緒 B 獲取資源的順序要一樣,當執行緒 A 是先嚐試獲取資源 A,然後嘗試獲取資源 B 的時候,執行緒 B 同樣也是先嚐試獲取資源 A,然後嘗試獲取資源 B。也就是說,執行緒 A 和 執行緒 B 總是以相同的順序申請自己想要的資源。
我們使用資源有序分配法的方式來修改前面發生死鎖的程式碼,我們可以不改動執行緒 A 的程式碼。
我們先要清楚執行緒 A 獲取資源的順序,它是先獲取互斥鎖 A,然後獲取互斥鎖 B。
所以我們只需將執行緒 B 改成以相同順序的獲取資源,就可以打破死鎖了。