死鎖與飢餓的區別
- 死鎖:死鎖是指多個進程一直得不到某個資源,而且不會釋放本身已經擁有的資源,一直等待下去。
- 飢餓:飢餓是指一個進程長時間得不到本身須要的某個資源
死鎖必定屬於飢餓,可是飢餓不必定是死鎖,可能某個時間只會又會獲得所需的資源,則飢餓解除。飢餓能夠只有一個進程參與,好比某個進程申請一個沒有的資源。死鎖至少有兩個進程。算法
死鎖的四個必要條件
- 資源互斥:即某個資源同一時間只能給一個進程使用,資源不可共享。
- 已擁有的資源不可被剝奪:一個進程已經擁有的資源不可被其餘進程剝奪
- 已擁有的資源不會主動放棄:一個進程已經擁有的資源不會主動放棄
- 等待:某個資源沒有申請到的時候一直等待
預防死鎖
破壞死鎖的四個必要條件,就能防止死鎖,資源互斥不可能破壞,資源共享容易發生問題,通常同一時間只能被一個進程使用,所以能夠考慮破壞其餘三個條件markdown
- 破壞《已擁有的資源不可被剝奪》:當某個進程申請不到某個資源時,操做系統強制或者進程本身主動釋放已經擁有的資源,或者操做系統強制讓用用這個資源的進程釋放資源
- 破壞《已擁有的資源不會主動放棄》:在申請資源的時候,主動釋放掉已經擁有的資源,即便立刻就要用到
- 破壞《等待》:在進程開始運行前先申請好全部的資源,要麼都申請到,要麼一個都不要。這樣就不會有等待的需求了。
避免死鎖
預防死鎖和避免死鎖的區別:
預防死鎖是設法至少破壞產生死鎖的四個必要條件之一,嚴格的防止死鎖的出現,在進程運行以前就能確保確定不會發生死鎖
而避免死鎖則不那麼嚴格的限制產生死鎖的必要條件的存在,由於即便死鎖的必要條件存在,也不必定發生死鎖。避免死鎖是在進程運行過程當中注意避免死鎖的最終發生。oop
- 資源統一編號:把全部資源統一編號,進程在運行過程當中隨時能夠申請資源,可是必須按照編號遞增順序,若是某個地方須要申請編號爲n的資源,則在這以前必須先申請好編號1到n的資源。這樣進程在申請某個資源而不得的時候就不會擁有這個資源前面的資源,就不會發生死鎖。
- 銀行家算法
檢測死鎖
死鎖的預防和避免都是在進程申請資源時進行控制,但在申請資源時控制也會有一些成本,有的算法實現難度大,若是在進程申請資源時不控制,即容許死鎖的發生,則必須提供死鎖的檢測和接觸方法。spa
- 資源分配圖:用圓圈表明一個進程,用框表明一類資源。因爲一種類型的資源可能有多個,用框中的一個點表明一類資源中的一個資源。從進程到資源的有向邊叫請求邊,表示該進程申請一個單位的該類資源;從資源到進程的邊叫分配邊,表示該類資源已經有一個資源被分配給了該進程。
上圖所示的資源分配圖中,進程P1已經分得了兩個R1資源,並又請求一個R2 資源;進程P2分得了一個R1和一個R2資源,並又請求一個R1資源。
檢測上述系統釋放死鎖的步驟以下:
1.檢查全部節點,若是某個進程可以運行完(即它所申請的資源足夠多,能夠知足它的運行),則假設這個進程已經運行完,去掉它鎖擁有的全部資源.
2.循環遍歷全部進程節點,按步驟1操做,最終若是上圖中全部的邊都消失了,則稱該系統是可徹底簡化的。
可簡化的系統就沒有發生死鎖,不可簡化的系統則發生了死鎖。
操作系統
解除死鎖
解除死鎖就是破壞上圖的引用關係,使得上圖變成可簡化的系統。主要有如下三種方法:.net
- 資源剝奪:掛起某些死鎖進程,並搶佔它的資源,將這些資源分配給其餘的死鎖進程。但應防止被掛起的進程長時間得不到資源,而處於資源匱乏的狀態。
- 強制殺死進程:強制撤銷部分、甚至所有死鎖進程並剝奪這些進程的資源。撤銷的原則能夠按進程優先級和撤銷進程代價的高低進行。
- 進程回退:讓一(多)個進程回退到足以迴避死鎖的地步,進程回退時自願釋放資源而不是被剝奪。要求系統保持進程的歷史信息,設置還原點。
參考
【1】死鎖,死鎖的四個必要條件以及處理策略
【2】死鎖的檢測和解除
code