1. 程式人生 > >【作業系統】處理死鎖的方法

【作業系統】處理死鎖的方法

破壞死鎖的四個必要條件中的一個或幾個。

預防死鎖

  • 破壞互斥條件
  • 破壞請求和保持條件
  • 破壞不可剝奪條件
  • 破壞環路等待條件

破壞互斥條件

即允許多個程序同時訪問資源。但由於資源本身固有特性的限制,此方法不可行。

破壞請求和保持條件

第一種協議

全分配,全釋放: 採用預先靜態分配方法,即要求程序在執行之前一次性申請它所需要的全部資源,在它的資源未滿足前,不把它投入執行。

若系統有足夠的資源,便可把程序需要的所有資源分配給它,在整個執行期間便不會再提出資源要求,從而摒棄了請求條件。在該程序的等待期間,它並未佔有任何資源,因而也摒棄了保持條件,這樣可以保證系統不會發生死鎖。

簡單安全,但資源浪費嚴重,可能有飢餓現象,同時必須預知程序所需要的全部資源。

第二種協議

允許一個程序只獲得執行初期所需的資源後,便開始執行。

摒棄保持條件:程序執行過程中必須釋放已分配給自己的且已經用完的全部資源,然後才能再請求新的所需資源。

第二種協議能使程序更快地完成任務,提高裝置利用率,還可減少程序飢餓的機率。

破壞不可剝奪條件

實施方案 1

在允許程序動態申請資源前提下,規定一個程序在申請新的資源不能立即得到滿足而變為等待狀態之前,必須釋放已佔有的全部資源,若需要再重新申請。

實施方案 2

程序申請的資源被其他程序佔用時,可以通過作業系統搶佔這一資源(適用於狀態易於儲存和恢復的資源) 。

破壞不可剝奪條件的方法實現較複雜,需付出很大的代價。會增加系統開銷,降低系統吞吐量,且程序前段工作可能失效。

破壞環路等待條件

採用有序資源分配方法,即將系統中所有資源都按型別賦予一個編號,要求每個程序均嚴格按照資源序號遞增的次序來請求資源, 從而保證任何時刻的資源分配圖不出現環路。

例如:系統把所有資源按型別進行排隊。如輸入機 =1,印表機 =2,磁帶機 =3,磁碟機 =4。

如果一個程序已經分配了序號為 i 資源,它接下來請求的資源只能是那些排在 i 之後的資源。

i<j時,程序 A 獲得 Ri,可以請求 Rj,而程序 B 獲得 Rj 再請求 Ri不可能發生,因為資源 Ri 排在 Rj 前面。

在採用這種策略時,總有一個程序佔據了較高序號的資源,此後它繼續申請的資源必然是空閒的,因而程序可以一直向前推進。

有序資源分配方法的缺點:新增資源不便(原序號已排定) ,使用者不能自由申請資源,加重了程序負擔。使用資源順序與申請順序不同可能造成資源浪費。

避免死鎖

不需要事先採取限制措施破壞產生死鎖的必要條件(死鎖預防); 在資源的動態分配過程中, 採用某種策略防止系統進入不安全狀態, 從而避免發生死鎖。

在系統執行過程中,對程序發出的每一個系統能夠滿足的資源申請進行動態檢查,並根據檢查結果決定是否分配資源,若分配後系統可能發生死鎖,則不予分配,否則予以分配。

系統的安全狀態

安全狀態指在某一時刻,系統能按某種程序順序(p1,p2,…,pn) 來為每個程序 Pi 分配其資源,直到滿足每個程序對資源的最大需求,使每個程序都可順利地完成,則稱此時的系統狀態為安全狀態,稱序列(p1,p2,…,pn) 為安全序列。若某一時刻系統中不存在這樣一個安全序列,則稱此時的系統狀態為不安全狀態。

在死鎖避免的方法中,允許程序動態申請資源,系統在進行資源分配之前,先計算資源分配的安全性,若此次分配不會導致系統進入不安全狀態,便將資源分配給程序,否則程序等待。

死鎖狀態空間

如果一個系統處於安全狀態,就不會死鎖。

如果一個系統處於不安全狀態,就有可能死鎖。

避免死鎖的實質:確保系統不進入不安全狀態。

圖示

安全狀態例項

例:假定系統中有三個程序 P1、P2 和 P3,共有 12 臺印表機,三個程序對印表機的需求和佔有情況如下表所示:

圖示

T0 時刻,存在一個安全序列(P2,P1,P3) ,所以系統是安全的。

安全序列可能不唯一

由安全狀態向不安全狀態的轉換

上例中,若 P3 再申請一臺,則進入不安全狀態。

圖示

在 P3 請求資源時,儘管系統中尚有可用的印表機,但卻不能分配給它,必須讓 P3 一直等待到 P1 和 P2 完成,釋放出資源後再將足夠的資源分配給 P3。

銀行家演算法(Banker’s Algorithm)

銀行家演算法是最具代表性的避免死鎖演算法(Dijkstra 於1965 年提出)

銀行家演算法的實質:設法保證系統動態分配資源後不進入不安全狀態,以避免可能產生的死鎖。

檢查是否有足夠的剩餘資金滿足一個距最大請求最近的客戶。如果有,這筆貸款被認為是能夠收回的。繼續檢查下一個客戶,如果所有投資最終都被收回,那麼該狀態是安全的,最初的請求可以批准。

銀行家演算法執行的前提條件:要求程序必須預先提出自己的最大資源請求數量,這一數量不能超過系統資源的總量,系統資源的總量是一定的。

銀行家演算法中的資料結構

假定系統中有 n 個程序(P1,P2, …,Pn) ,m 類資源(R1,R2, …,Rm) ,銀行家演算法中使用的資料結構如下:

可利用資源向量:Available[j]=k,表示 Rj類資源有 k 個可用

最大需求矩陣:Max[i,j]=k,程序 Pi最大請求 k 個 Rj類資源

分配矩陣:Allocation[i,j]=k,程序 Pi已經分配到 k 個Rj類資源

需求矩陣:Need[i,j]=k,程序 Pi還需要 k 個 Rj 類資源

Need [i,j] = Max [i,j] – Allocation [i,j]

銀行家演算法描述(資源分配演算法)

假定程序 Pi 請求分配 Rj 類資源 k 個,設 Request[i,j]=k。當程序Pi 發出資源請求後,系統按如下步驟進行檢查:

1 如果 Request[i,j] ≤Need[i,j] ,轉 (2);否則出錯,因為程序申請資源量超過它宣告的最大量。

2 如果 Request[i,j] ≤Available[j] ,轉 (3);否則表示資源不夠,需等待。

3 系統試分配資源給程序 Pi,並作如下修改:
Available[j]= Available[j] - Request[i,j]
Allocation[i,j]= Allocation[i,j] + Request[i,j]
Need[i,j]= Need[i,j] - Request[i,j]

4 系統執行安全性演算法。若安全,則正式進行分配,否則恢復原狀態讓程序 Pi 等待。

銀行家演算法描述(安全性演算法)

為了進行安全性檢查,需要定義如下資料結構:

1 工作變數 work[m]:記錄可用資源。開始時,Work=Available。

2 finish[n]:記錄系統是否有足夠的資源分配給程序,使之執行完成。開始時,finish[i]=false;當有足夠資源分配給程序 Pi 時,令finish[i]=true。

圖解

銀行家演算法例題1

例:假定系統中有 5 個程序 P0 到 P4,3 類資源及數量分別為 A(10 個) ,B(5 個) ,C(7 個) ,T0 時刻的資源分配情況如下:

圖示

過程圖

P1 發出請求向量 Request1(1,0,2)
已知 Need1 (1,2,2),Available (3,3,2)
系統按銀行家演算法進行檢查:

Request1 (1,0,2) ≤ Need1 (1,2,2)
Request1 (1,0,2) ≤ Available (3,3,2)
系統試為 P1 分配資源,並修改相應的向量Available、Need、Allocation

圖示

圖示

P4 發出請求向量 Request4(3,3,0),系統按銀行家演算法進行檢查:

Request4(3,3,0) ≤ Need4 (4,3,1)
Request4 (3,3,0) > Available (2,3,0)

資源不夠,讓 P4 等待

P0 請求資源 Request0(0,2,0)

P0 發出請求向量 Request0(0,2,0),系統按銀行家演算法進行檢查:

Request0(0,2,0) ≤ Need0 (7,4,3)
Request0 (0,2,0) ≤ Available (2,3,0)

系統試為 P0 分配資源,並修改相應的向量
Available、Need、Allocation

圖示

圖示

銀行家演算法例題2

T0 時刻的資源分配情況如下:

圖示

剩餘資源向量為:Available = (2, 3, 3)

1.T0 時刻是否為安全狀態?若是,請給出安全序列。

圖示

2.在 T0 時刻若程序 P2 請求資源(0,3,4) ,是否能實施資源分配?

因為 Request2(0, 3, 4)> Available (2, 3, 3)所以不能滿足程序 P2 的請求。

3.若程序 P4 請求資源(2,0,0) ,是否可以資源分配?

Request4(2, 0, 0)≤ Need4 (2, 0, 1)
且 Request4(2, 0, 0)< Available(2, 3, 3)
試分配後,則 Need4 =(0, 0, 1), Allocation4 =(4, 0, 4)
新的剩餘向量 Available = (0, 3, 3)

圖示

銀行家演算法流程圖

圖示

死鎖避免小結

優點

  • 比死鎖預防限制少。
  • 無死鎖檢測方法中的資源剝奪, 程序重啟。

缺點

  • 必須事先宣告每個程序的最大資源請求。
  • 考慮的程序必須是無關的, 也就是說, 它們執行的順序沒有任何同步要求的限制。
  • 程序的數量保持固定不變,且分配的資源數目必須是固定的。

死鎖的檢測和解除

如果在一個系統中,既未採用死鎖預防方法,也未採用死鎖避免方法,而是直接為程序分配資源,則系統中便有可能發生死鎖。

一旦死鎖發生,系統應能將其找到並加以消除,為此需提供死鎖檢測和解除死鎖的手段。

檢測死鎖的基本思想:在作業系統中儲存資源的請求和分配資訊,利用某種演算法對這些資訊加以檢查,以判斷是否存在死鎖。

資源分配圖

資源分配圖又稱程序 -資源圖,它是描述程序和資源間的申請和分配關係的一種有向圖。

圓圈表示程序節點 P,方框表示資源節點 R,方框中的小黑點數表示資源數。

請求邊:Pi →Rj 分配邊:Pi ←Rj

圖示

圖示

上圖中:r2中有兩個資源,分別分配給了p1和p2,然後p1請求r1,而r1中就1個資源,分配給了p2,所以此時p1阻塞,p2請求r3,而r3中的那個資源分配給了p3,所以此時p2也阻塞,r4中的一個資源分配給了p3,所以,待p3執行完畢,釋放r3,p2阻塞解除,執行完畢後釋放r1,然後p1執行。下面也都同樣的分析思路,此處不再詳解。

圖示

重要結論:如果資源分配圖中不存在環路,則系統中不存在死鎖;反之,如果資源分配圖中存在環路,則系統中可能存在死鎖,也可能不存在死鎖。

死鎖定理

資源分配圖的化簡方法
1 尋找一個既不阻塞又不孤立的程序結點 Pi,若無則演算法結束;
2 去除 Pi 的所有分配邊和請求邊,使 Pi 成為一個孤立結點;
3 轉步驟(1) 。

在進行一系列化簡後,若能消去圖中所有的邊,使所有程序都成為孤立結點,則稱該圖是可完全簡化的;反之,稱該圖是不可完全簡化的。

孤立結點:沒有請求邊和分配邊與之相連。

阻塞結點:有請求邊但資源無法滿足其要求。

死鎖定理:出現死鎖狀態的充分條件是資源分配圖不可完全簡化。

圖示

圖示

圖示

死鎖的檢測

死鎖檢測演算法的思想

死鎖檢測演算法的思想是基於資源分配圖化簡和死鎖定理來檢測死鎖。

死鎖檢測的原因

系統沒有采取任何預先限制死鎖的措施。資源分配時不檢查系統是否會進入不安全狀態, 被請求的資源都被授予給程序。需要週期性檢測是否出現死鎖。

檢測時機

  • 在每個資源請求時都進行(相當於死鎖避免) 。
  • 定時檢測。
  • 系統資源利用率下降時檢測死鎖。

死鎖檢測中的資料結構類似於銀行家演算法的資料結構:

圖示

死鎖檢測流程

圖示

檢測演算法練習題

圖示

圖示

死鎖的解除

一旦檢測出系統中出現了死鎖,就應將陷入死鎖的程序從死鎖狀態中解脫出來,常用的解除死鎖方法有兩種:

資源剝奪法: 當發現死鎖後,從其它程序剝奪足夠數量的資源給死鎖程序,以解除死鎖狀態。

  • 撤消程序法: 採用強制手段從系統中撤消一個/一部分死鎖程序,並剝奪這些程序的資源供其它死鎖程序使用。
  • 撤消全部死鎖程序。
  • 按照某種順序逐個地撤消程序,直至有足夠的資源可用,使死鎖狀態消除為止。

基於最小代價原則一次只終止一個程序直到取消死鎖迴圈為止。

撤消程序選擇原則

  • 已消耗 CPU 時間最少
  • 到目前為止產生的輸出量最少
  • 預計剩餘的時間最長
  • 目前為止分配的資源總量最少
  • 優先順序最低