多程序,多執行緒的併發執行雖然提公升了系統資源的利用率,提高了系統的效能,但是併發執行也帶來了新的問題-----死鎖。
死鎖是指多個程序(執行緒)在執行過程中,由於競爭資源或者由於彼此通訊而造成的一種阻塞的現象(互相掛起等待),若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的程序稱為死鎖程序
舉乙個生活中的簡單例子:小明和小紅都想買一塊橡皮,這塊橡皮價值一塊錢,但是他們倆每個人都只有五毛錢,小明說:你把你的五毛錢給我,讓我買橡皮。小紅說:你把你的五毛錢給我,讓我買橡皮。這樣,兩個人互相僵持著,誰也不願意低頭,誰都買不到橡皮。
為了保證執行緒之間的同步和互斥,我們往往需要給其加鎖,有時候,執行緒申請了鎖資源,還沒有等待釋放,又一次申請這把鎖,結果就是掛起等待這把鎖的釋放,但是這把鎖是被自己拿著,所以就會永遠掛起等待,就造成了死鎖。
有兩個執行緒p1和p2,p1首先申請得到了鎖l1,p2申請得到了鎖l2,這個時候p1有向去申請鎖l2,結果是被掛起等待p2釋放鎖l2,而p2恰好也想申請鎖l1,結果是掛起等待p1釋放鎖l1,此時就造成兩個執行緒互相僵持,造成死鎖。
有三個執行緒,p1,p2和p3,分別生產資料m1,m2,m3,同時分別接收別的執行緒產生的資料m3,m2,m1,如果執行緒推進的順序正確,即三個執行緒都先生產資料,再接收,那麼沒有問題,但是一旦執行緒先接受資料,再生產資料,因為一開始沒有資料產生,那麼就會造成三個執行緒的死鎖問題。
系統的資源不足。
程序(執行緒)推進的順序不對。
資源的分配不當。
當系統的資源很充沛的時候,每個程序都可以申請到想要的資源,那麼出現死鎖的概率就很低,執行緒的排程順序和速度不同,也會導致死鎖問題。
互斥條件:程序(執行緒)申請的資源在一段時間中只能被乙個程序(執行緒)使用。
請求與等待條件:程序(執行緒)已經擁有了乙個資源,但是又申請新的資源,擁有的資源保持不變 。
不可剝奪條件:在乙個程序(執行緒)沒有用完,主動釋放資源的時候,不能被搶占。
迴圈等待條件:多個程序(執行緒)之間存在資源迴圈鏈。
預防死鎖:破壞死鎖產生的四個條件之一,注意,互斥條件不能破壞。
避免死鎖:合理的分配資源。
檢查死鎖:利用專門的死鎖機構檢查死鎖的發生,然後採取相應的方法。
解除死鎖:發生死鎖時候,採取合理的方法解決死鎖。一般是強行剝奪資源。
打破互斥條件:改造獨占性資源為虛擬大資源,但是大部分資源無法改造,因此不建議使用這個方法。
打破請求與保持條件:在程序(執行緒)執行之前,就把需要申請的資源一次性申請到位,滿足則執行,不滿足就等待,這樣就不會造成在占有資源的情況下,還要申請新資源。
打破不可剝奪條件:在占有資源並且還想要申請新資源的時候,歸還已經占有的資源。
打破迴圈等待條件:實現資源的有序分配,即對所有的裝置進行分類編號,只能以公升序的方式來申請資源。
比如說程序p1,使用資源的順序是r1,r2,程序p2,使用資源的順序是r2,r1,如果採取動態分配的方式,就很有可能造成死鎖。我們對裝置進行分類編號,那麼p1,p2只能以r1,r2的順序來申請資源。就可以打破環形迴路,避免死鎖。
在避免死鎖的方法中最有名的就是銀行家演算法,它是dijkstra e.w於2023年提出來的。
為什麼叫做銀行家演算法呢,是因為這有點向銀行的「借貸」服務,假如銀行只有有限多的資金供給客戶進行貸款服務,那麼為了保證銀行能有足夠的資金運轉,它在借錢之前要審核客戶是否有能夠在指定時間內償還貸款的能力。
在研究我們的作業系統的資源分配策略時,也會出現類似的問題,我們系統中的有限資源要分配給各種程序,那麼就要事先考察此程序是否有在指定期限內歸還資源的能力。必須要保證它能在有限的時間內進行歸還,拱其他程序使用。
大致實現方法:
當乙個程序對資源的最大需求量不超過系統中的資源數時可以接納該程序。
程序可以分期請求資源,當請求的總數不能超過最大需求量。
當系統現有的資源不能滿足程序尚需資源數時,對程序的請求可以推遲分配,但總能使程序在有限的時間裡得到資源。
當系統現有的資源能滿足程序尚需資源數時,必須測試系統現存的資源能否滿足該程序尚需的最大資源數,若能滿足則按當前的申請量分配資源,否則也要推遲分配。
銀行家演算法:首先需要定義狀態和安全狀態的概念。系統的狀態是當前給程序分配的資源情況。因此,狀態包含兩個向量resource(系統中每種資源的總量)和**ailable(未分配給程序的每種資源的總量)及兩個矩陣claim(表示程序對資源的需求)和allocation(表示當前分配給程序的資源)。安全狀態是指至少有乙個資源分配序列不會導致死鎖。當程序請求一組資源時,假設同意該請求,從而改變了系統的狀態,然後確定其結果是否還處於安全狀態。如果是,同意這個請求;如果不是,阻塞該程序知道同意該請求後系統狀態仍然是安全的。
JAVA多執行緒死鎖詳解
需要避免的與多工處理有關的特殊錯誤型別是死鎖 deadlock 死鎖發生在當兩個執行緒對一對同步物件有迴圈依賴關係時。例如,假定乙個執行緒進入了物件x的管程而另乙個執行緒進入了物件y的管程。如果x的執行緒試圖呼叫y的同步方法,它將像預料的一樣被鎖定。而y的執行緒同樣希望呼叫x的一些同步方法,執行緒永...
執行緒中的死鎖詳解
在多執行緒場景中,多個執行緒互相持有對方需要的鎖,從而造成了阻塞。嚴重影響了效能。常見的死鎖 順序死鎖,動態死鎖 賬 順序死鎖的示例 public class test class aextends thread public void run catch interruptedexception ...
UNIX環境高階程式設計 執行緒 死鎖詳解
一 死鎖產生原因 執行緒對同乙個互斥量加鎖兩次,那麼它自身就會陷入死鎖狀態 多個互斥量,多個執行緒交叉請求訪問衝突。例如,程式中使用乙個以上的互斥量時,如果允許乙個執行緒一直占有第乙個互斥量,並且在試圖鎖住第二個互斥量時處於阻塞狀態,但是擁有第二個互斥量的執行緒也在試圖鎖住第乙個互斥量。因為兩個執行...