1. 程式人生 > >第三章 死鎖 銀行家演算法

第三章 死鎖 銀行家演算法

                                                     關於死鎖

多道程式系統藉助併發執行改善資源利用率,提高系統吞吐量,但可能發生一種危險——死鎖。
死鎖(Deadlock):指多個程序在執行過程中,因爭奪資源而造成的一種僵局。當程序處於這種狀態時,若無外力作用,它們都將無法再向前推進。

死鎖(Deadlock): 指程序之間無休止地互相等待!
飢餓(Starvation):指一個程序無休止地等待!
在這裡插入圖片描述
四、產生死鎖的原因和必要條件
產生死鎖的原因可歸結為如下兩點:
1競爭資源。系統中供多個程序共享的資源如印表機、公用佇列等的數目不滿足需要時,會引起資源競爭而產生死鎖。
2程序間推進順序非法。程序在執行過程中,請求和釋放資源的順序不當,同樣會導致死鎖。

1、競爭資源引起程序死鎖
可把系統中的資源分為兩類:
可剝奪和非剝奪性資源
可剝奪性資源:分配給程序後可以被高優先順序的程序剝奪。如CPU和主存。
不可剝奪性資源:分配給程序後只能在程序用完後釋放。如磁帶機、印表機等。
永久性資源和臨時性資源
永久性:印表機。可順序重複使用
臨時性:程序產生被其他程序短暫使用的資源,如資料資源:“生產者/消費者”演算法中的訊號量。。它可能引起死鎖。

2、程序推進順序不當引起死鎖
程序在執行中具有非同步性特徵,多個程序按向前推進的順序有兩種情況:
推進順序合法
推進順序非法

在這裡插入圖片描述
3、 產生死鎖的必要條件
形成死鎖的四個必要條件(四個條件都具備就會死鎖,缺一就不會死鎖)
a.互斥條件:程序對所分配到的資源進行排他性使用
b.請求和保持條件:程序已經保持了至少一個資源,又提出新的資源請求,而新請求資源被其他程序佔有只能造成c.自身程序阻塞,但對自己已獲得的其他資源保持不放,必然影響其他程序。
d.不剝奪條件:程序已獲得的資源未使用完之前不能被剝奪,只能在使用完時由自己釋放。
環路等待條件

4、處理死鎖的基本方法
事先預防:
①預防死鎖
設定限制條件,破壞四個必要條件的一個或幾個,預防發生死鎖。
較易實現。限制條件的嚴格也會導致系統資源利用率和系統吞吐量降低。
②避免死鎖
不須事先限制,破壞四個必要條件,而是在資源的動態分配過程中,用某種方法去防止系統進入不安全狀態,從而避免發生死鎖。
這種事先加以較弱限制的方法,實現上有一定難度,但可獲較高的資源利用率及系統吞吐量,目前在較完善的系統中,常用此方法來避免發生死鎖。

事後處理:
③檢測死鎖。
允許系統執行過程中發生死鎖,但通過系統檢測機構可及時的檢測出,能精確確定與死鎖有關的程序和資源;然後採取適當的措施,從系統中將已發生的死鎖清除掉。
④解除死鎖。
與死鎖檢測配套的一種措施。
常用的實施方法:撤銷或掛起一些程序,以便回收一些資源並將他們分配給已阻塞程序,使之轉為就緒以繼續執行。
死鎖的檢測與解除措施,有可能使系統獲得較好的資源利用率和吞吐量(死鎖機率不一定很高),但在實現上難度也最大。

五、預防死鎖的方法

預防死鎖
資源的排他性無法更改,故在其他3個條件上入手
①摒棄“請求和保持”條件:所有程序開始執行前,必須一次性的申請其在整個執行過程所需的全部資源(AND)。演算法簡單、易於實現且很安全。但缺點是資源浪費嚴重、或程序延遲執行。
②摒棄“不剝奪”條件:允許程序先執行,但當提出的新要求不被滿足時必須釋放它已保持的所有資源,待以後需要時再重新申請。實現比較複雜且付出很大代價。可能會造成前功盡棄,反覆申請和釋放等情況。
③摒棄“環路等待”條件
有序設定資源:將所有資源按型別進行線性排隊,賦予不同序號。所有程序對資源的請求必須嚴格按照資源序號遞增的次序提出,這樣在所形成的資源分配圖中,不可能會出現環路。
與前兩種策略比較,資源利用率和系統吞吐量都有較明顯的改善。但也存在嚴重問題:
資源編號限制新裝置的增加;
應用中的使用裝置順序與規定的順序並不協調;
限制了使用者程式設計自由。
在這裡插入圖片描述
可能的死鎖狀態(4個位置都填滿): (1)E方向兩輛車分別位於A和B;S方向一輛車位於C;W方向一輛車位於D。 (2)S方向兩輛車分別位於B和C;E方向一輛車位於A;W方向一輛車位於D。
預防死鎖的處理(對資源請求按單向順序)
為位置資源C、B、A、D設定四個訊號量s1,s2,s3,s4,訊號量的初值均為1
對他們的使用規定按順序從低到高編號為1、2、3、4
使用四個位置的訊號量必須按規定順序申請資源,車輛活動程式碼如下:
在這裡插入圖片描述
2.避免死鎖
上述方法限制條件都太強;造成一定的應用不便。採用避免死鎖的方法則是隻施加較弱限制條件,從而獲得令人滿意的系統性能。
名詞:
安全狀態:系統能按某種程序順序為每個程序分配所需資源,直至滿足每個程序對資源的最大需求,並能順利完成。
不安全狀態:系統無法找到一種使多個程序能夠順利分配資源執行完的安全序列。

安全狀態、安全序列舉例
假定三個程序A、B和C,共有12臺磁帶機。
假設 t0 時刻,磁帶機資源分配情況如下表所示,此時系統是否處於安全狀態
在這裡插入圖片描述
是安全的,因為存在一個安全序列B,A,C
只要系統按此程序序列分配資源,就能使每個程序都順利完成。

由安全狀態向不安全狀態的轉換
每次資源分配時,都應分析判斷資源分配圖,看該次操作後是否有安全序列。若沒有,說明該操作會使系統進入不安全狀態。
只要使系統始終處於安全狀態,便可避免發生死鎖。
不是所有的不安全狀態都是死鎖狀態。

  1. 銀行家演算法避免死鎖
    最有代表性的避免死鎖的演算法,是Dijkstra的銀行家演算法。由於該演算法能用於銀行系統現金貸款的發放而得名。
    【思路描述】:隨時對系統中的所有資源資訊進行統計,包括每種資源的數量、已分配給各程序的數量;每當程序提出某種資源請求時判斷該請求分配後是否安全,如果安全才分配。對每個資源請求的處理都要保證系統始終從一個安全狀態到另一個安全狀態。

銀行家演算法應用之例
假定系統中有五個程序{P0,P1,P2,P3,P4}和三類資源{A,B,C},各種資源的數量分別為10、5、7,在T0時刻的資源分配情況如圖所示。
在這裡插入圖片描述
計算舉例:當前T0時刻是否安全?
利用安全性演算法在下表找一個安全序列{P1,P3,P4,P2,P0},故是安全的。(最後檢查應是資源釋放完後又回到10、5、7 )
在這裡插入圖片描述
找安全序列的計算過程表
在這裡插入圖片描述
1)T0時刻的初始狀態是安全的;
(2)下面出現P1請求資源的操作,具體請求向量為Request1(1,0,2),利用銀行家演算法進行檢查該操作是否是安全可行的:
1)兩個基本判斷
Request1(1,0,2)<=Need1(1,2,2)
Request1(1,0,2)<=Available1(3,3,2)
2)先假設為P1分配資源,並修改Available,Allocation1和Need1向量。

3) Request1(1,0,2)後新的資源狀態表下再判斷新資源狀態是否是安全的。
找到一個安全序列{P1,P3,P4,P0,P2},因此係統是安全的,該請求是安全的,可將假設真正實施,將P1所申請的資源分配給它。
在這裡插入圖片描述
問:P4發出請求向量Request4(3,3,0),可否分配資源?
1)Request4(3,3,0)<=Need4(4,3,1);
2)Request4(3,3,0)<=Available(2,3,0),P4等待
問:P0發出請求向量Request0(0,2,0),可否分配資源?
1)Request0(0,2,0)<=Need0(7,4,3);
2)Request0(0,2,0)<=Available(2,3,0);
3)系統暫時先假定可為P0分配資源,並修改有關資料,見下表:
在這裡插入圖片描述
Available(2,1,0)不能滿足任何finish=false程序的需求,如果分配會使系統進入不安全狀態,所以不能分配資源。
如果把P0發出的請求向量改為Request0(0,1,0),系統是否能將資源分配給它,大家考慮。

演算法實現說明
演算法實現:
首先:需要的一些資料結構
再次:演算法過程
核心:安全性判斷演算法

m類資源,n個併發程序對其產生需求
1)銀行家演算法中的資料結構
(1)各類可利用資源的數量
向量Available :(i1,i2,…,im),含m個元素,每個元素代表一類可利用的資源數目。
動態變化的,初始值是系統配置的該類資源的全部數目,值隨資源的分配與回收而動態的改變。
實現:一維陣列。Available【j】=K,表示系統中Rj類資源現有可用數量為K個。
(2)每個程序對每類資源的需求
最大需求、已獲得的、還需要的
最大需求矩陣Max
nm,系統中n個程序中每個程序分別對m類資源的最大需求。
取值:根據程序需求賦初始值。
實現:二維陣列。Max【i,j】=K,表示程序 i 需要Rj類資源的最大數目為K。
已分配矩陣Allocation。
n
m,定義系統中每一程序已獲得的每類資源數量。
Allocation【i,j】=K,表示程序i當前已分得Rj類資源數為K。
還需求的矩陣Need。
n*m,表示每一程序尚需的各類資源數。
Need【i,j】=K,表示程序i還需要Rj類資源K個,方能完成任務。
上述三個矩陣存在關係:
Max【i,j】= Allocation【i,j】+Need【i,j】
每次,給程序 i 分配資源的動作,影響上述資料結構的取值:
Available【  】,Allocation【i,】,Need【i,】

2)避免死鎖的演算法過程(銀行家演算法)
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
六、死鎖的檢測與解除
當系統為程序分配資源時,若未採取任何限制性措施,則系統必須提供檢測和解除死鎖的手段,為此係統必須:
儲存有關資源的請求和分配資訊;
提供一種演算法,以利用這些資訊來檢測系統是否已進入死鎖狀態。

1、資源分配圖
系統死鎖可利用資源分配圖來描述。
圓圈表示程序
方框表示一類資源,其中的一個點代表一個該類資源
請求邊由程序指向方框中的資源
分配邊則由方框中的一個點即資源。
在這裡插入圖片描述
死鎖的檢測

檢測時機:
當程序等待時檢測死鎖
定時檢測
系統資源利用率下降時檢測死鎖
2、死鎖定理
利用資源分配圖簡化法來檢測死鎖。
簡化方法如下:
1.在資源分配圖中找出一個既不阻塞又非獨立的程序結點Pi,在順利的情況下執行完畢,釋放其佔有的全部資源。
2.由於釋放了資源,這樣能使其它被阻塞的程序獲得資源繼續執行。消去了Pi的邊。
3.經過一系列簡化後,若能消去圖中所有邊,使結點都孤立,稱該圖是可完全簡化的。
S狀態為死鎖狀態的充分條件是當且僅當S狀態的資源分配圖是不可完全簡化的。<死鎖定理>
在這裡插入圖片描述
每類資源只有一個資源
死鎖檢測演算法:

  • 每個程序和資源指定唯一編號

  • 設定一張資源分配表
    記錄各程序與其佔用資源之間的關係

  • 設定一張程序等待表
    記錄各程序與要申請資源之間的關係
    反覆檢測這兩張表,列出所有等待與分配的關係,若出現迴圈等待,則出現了死鎖!
    3、 死鎖的解除
    當發現程序死鎖時,便應立即把它們從死鎖狀態中解脫出來。常採用的方法是:
    剝奪資源。從其他程序剝奪足夠數量的資源給死鎖程序以解除死鎖狀態。
    撤銷程序。最簡單的是讓全部程序都死掉;溫和一點的是按照某種順序逐個撤銷程序,直至有足夠的資源可用,使死鎖狀態消除為止。

                                                          死鎖處理方法比較
    

在這裡插入圖片描述