1. 程式人生 > >死鎖四個必要條件及死鎖的預防、檢測、避免、解除

死鎖四個必要條件及死鎖的預防、檢測、避免、解除

死鎖:

我們先來思考一個問題:我們加鎖以後,再次進行加鎖,這樣會發生什麼?

當我們第二次申請鎖的時候,這個時候鎖已經被佔用了,該執行緒就會被掛起,但是剛好這個執行緒就是擁有鎖的執行緒了,那麼這個執行緒就永遠掛起等待了,這個我們就叫死鎖。

1.死鎖發生的情形:

(1)一個執行緒兩次申請鎖。

(2)兩個執行緒互相申請對方的鎖,但是對方都不釋放鎖。

2.死鎖產生的必要條件:

(1) 互斥:一次只有一個程序可以使用一個資源。其他程序不能訪問已分配給其他程序的資源。

(2)佔有且等待:當一個程序在等待分配得到其他資源時,其繼續佔有已分配得到的資源。

(3)非搶佔:不能強行搶佔程序中已佔有的資源。

(4)迴圈等待:存在一個封閉的程序鏈,使得每個資源至少佔有此鏈中下一個程序所需要的一個資源。

3.處理死鎖的四種方法:

(1)死鎖預防:通過確保死鎖的一個必要條件不會滿足,保證不會發生死鎖

(2)死鎖檢測:允許死鎖的發生,但是可以通過系統設定的檢測結構及時的檢測出死鎖的發生,採取一些措施,將死鎖清除掉

(3)死鎖避免:在資源分配過程中,使用某種方法避免系統進入不安全的狀態,從而避免發生死鎖

(4)死鎖解除:與死鎖檢測相配套的一種措施。當檢測到系統中已發生死鎖,需將程序從死鎖狀態中解脫出來。

常用方法:撤銷或掛起一些程序,以便回收一些資源,再將這些資源分配給已處於阻塞狀態的程序。

4.處理死鎖的具體細節:

一、死鎖預防:破壞死鎖的四個條件中的一個或幾個

(1)互斥:它是裝置的固有屬性所決定的,不僅不能改變,還應該加以保證。
(2)佔有且等待:為預防佔有且等待條件,可以要求程序一次性的請求所有需要的資源,並且阻塞這個程序直到所有請求都同時滿足。這個方法比較低效。
(3)不可搶佔:預防這個條件的方法:
*如果佔有某些資源的一個程序進行進一步資源請求時被拒絕,則該程序必須釋放它最初佔有的資源。
*如果一個程序請求當前被另一個程序佔有的一個資源,則作業系統可以搶佔另外一個程序,要求它釋放資源。
(4)迴圈等待:通過定義資源型別的線性順序來預防。
*如果一個程序已經分配了R類資源,那麼接下來請求的資源只能是那些排在R型別之後的資源型別。該方法比較低效。

二、死鎖避免:

兩種死鎖避免演算法:

*程序啟動拒絕:如果一個程序的請求會導致死鎖,則不啟動該程序。
*資源分配拒絕:如果一個程序增加的資源請求會導致死鎖,則不允許此分配(銀行家演算法)。 

銀行家演算法:
1.如果request<=need,轉向步驟2;否則認為出錯,因為請求資源大於需要資源。
2.如果request<=available,轉向步驟3,;否則尚無足夠資源,程序p阻塞;
3.系統嘗試為把資源分配給程序P,並修改available、allocation和need的數值。
4.系統執行安全性演算法,檢查此次分配後系統是否處於安全狀態,若安全,才正式將資源分配給程序P,否則將本次試探性分配作廢,讓程序P等待。
*安全狀態:系統能按照某種程序順序,為每個程序分配資源,直至滿足每個程序對資源的最大需求,使每個程序都可順利完成。

三、死鎖檢測

一個簡單的死鎖檢測演算法:
每個程序、每個資源制定唯一編號      設定一張資源分配表,記錄各程序與佔用資源之間的關係      設定一張程序等待表,記錄各程序與要申請資源之間的關係

  •  資源分配表

資源 程序
r1 p2
r2 p5
r3 p4
r4 p1
.. ..

 程序等待表

資源 程序
p1 r1
p2 r3
p4 r4
.. ..


分析: 
p1-r1-p2-r3-p4-r4-p1 出現環路引起死鎖

(四)、死鎖的解除:

*兩種常用的死鎖解除方法:

1) 資源剝奪法。掛起某些死鎖程序,並搶佔它的資源,將這些資源分配給其他的死鎖程序。但應防止被掛起的程序長時間得不到資源,而處於資源匱乏的狀態。
2) 撤銷程序法。強制撤銷部分、甚至全部死鎖程序並剝奪這些程序的資源。撤銷的原則可以按程序優先順序和撤銷程序代價的高低進行。