1. 程式人生 > >死鎖預防與死鎖避免

死鎖預防與死鎖避免

死鎖預防

防止死鎖的發生只需破壞死鎖產生的四個必要條件之一即可。

1) 破壞互斥條件

如果允許系統資源都能共享使用,則系統不會進入死鎖狀態。但有些資源根本不能同時訪問,如印表機等臨界資源只能互斥使用。所以,破壞互斥條件而預防死鎖的方法不太可行,而且在有的場合應該保護這種互斥性。

2) 破壞不剝奪條件

當一個已保持了某些不可剝奪資源的程序,請求新的資源而得不到滿足時,它必須釋放已經保持的所有資源,待以後需要時再重新申請。這意味著,一個程序已佔有的資源會被暫時釋放,或者說是被剝奪了,或從而破壞了不可剝奪條件。

該策略實現起來比較複雜,釋放已獲得的資源可能造成前一階段工作的失效,反覆地申請和釋放資源會增加系統開銷,降低系統吞吐量。這種方法常用於狀態易於儲存和恢復的資源,如CPU的暫存器及記憶體資源,一般不能用於印表機之類的資源。

3) 破壞請求和保持條件

釆用預先靜態分配方法,即程序在執行前一次申請完它所需要的全部資源,在它的資源未滿足前,不把它投入執行。一旦投入執行後,這些資源就一直歸它所有,也不再提出其他資源請求,這樣就可以保證系統不會發生死鎖。

這種方式實現簡單,但缺點也顯而易見,系統資源被嚴重浪費,其中有些資源可能僅在執行初期或執行快結束時才使用,甚至根本不使用。而且還會導致“飢餓”現象,當由於個別資源長期被其他程序佔用時,將致使等待該資源的程序遲遲不能開始執行。

4) 破壞迴圈等待條件

為了破壞迴圈等待條件,可釆用順序資源分配法。首先給系統中的資源編號,規定每個程序,必須按編號遞增的順序請求資源,同類資源一次申請完。也就是說,只要程序提出申請分配資源Ri,則該程序在以後的資源申請中,只能申請編號大於Ri的資源。


這種方法存在的問題是,編號必須相對穩定,這就限制了新型別裝置的增加;儘管在為資源編號時已考慮到大多數作業實際使用這些資源的順序,但也經常會發生作業使甩資源的順序與系統規定順序不同的情況,造成資源的浪費;此外,這種按規定次序申請資源的方法,也必然會給使用者的程式設計帶來麻煩。

死鎖避免

避免死鎖同樣是屬於事先預防的策略,但並不是事先釆取某種限制措施破壞死鎖的必要條件,而是在資源動態分配過程中,防止系統進入不安全狀態,以避免發生死鎖。這種方法所施加的限制條件較弱,可以獲得較好的系統性能。

1. 系統安全狀態

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


所謂安全狀態,是指系統能按某種程序推進順序( P1, P2, ..., Pn),為每個程序Pi分配其所需資源,直至滿足每個程序對資源的最大需求,使每個程序都可順序地完成。此時稱 P1, P2, ..., Pn 為安全序列。如果系統無法找到一個安全序列,則稱系統處於不安全狀態。

假設系統中有三個程序P1、P2和P3,共有12 臺磁帶機。程序P1總共需要10臺磁帶機,P2和P3 分別需要4臺和9臺。假設在T0時刻,程序P1、P2 和P3已分別獲得5合、2臺和2臺,尚有3臺未分配,見表2-15。

表2-15 資源分配
程序 最大需求 已分配 可用
P1 10 5 3
P2 4 2
P3 9 2

則在T0時刻是安全的,因為存在一個安全序列P2、Pl、P3,即只要系統按此程序序列分配資源,則每個程序都能順利完成。若在T0時刻後,系統分配1臺磁帶機給P3,則此時系統便進入不安全狀態,因為此時已無法再找到一個安全序列。

並非所有的不安全狀態都是死鎖狀態,但當系統進入不安全狀態後,便可能進入死鎖狀態;反之,只要系統處於安全狀態,系統便可以避免進入死鎖狀態。

2. 銀行家演算法

銀行家演算法是最著名的死鎖避免演算法。它提出的思想是:把作業系統看做是銀行家,作業系統管理的資源相當於銀行家管理的資金,程序向作業系統請求分配資源相當於使用者向銀行家貸款。作業系統按照銀行家制定的規則為程序分配資源,當程序首次申請資源時,要測試該程序對資源的最大需求量,如果系統現存的資源可以滿足它的最大需求量則按當前的申請量分配資源,否則就推遲分配。當程序在執行中繼續申請資源時,先測試該程序已佔用的資源數與本次申請的資源數之和是否超過了該程序對資源的最大需求量。若超過則拒絕分配資源,若沒有超過則再測試系統現存的資源能否滿足該程序尚需的最大資源量,若能滿足則按當前的申請量分配資源,否則也要推遲分配。

1) 資料結構描述
可利用資源向量Available:含有m個元素的歎組,其中的每一個元素代表一類可用的資源數目。Available[j]=K,則表示系統中現有Rj類資源K個。

最大需求矩陣Max:為n*m矩陣,定義了系統中n個程序中的每一個程序對m類資源的最大需求。Max[i, j]=K,則表示程序i需要Rj類資源的最大數目為K。

分配矩陣Allocation:為n*m矩陣,定義了系統中每一類資源當前已分配給每一程序的資源數。All0Cati0n[i, j]= K,則表示程序i當前已分得Rj類資源的數目為K。

需求矩陣Need:為n*m矩陣,表示每個程序尚需的各類資源數。Need[i, j]=K,則表示程序i還需要Rj類資源的數目為K。

上述三個矩陣間存在下述關係:
Need[i, j] = Max[i, j] - Allocation[i, j]

2) 銀行家演算法描述
設Requesti是程序Pi的請求向量,如果Requesti[j]K,表示程序Pi需要Rj類資源K個。當Pi發出資源請求後,系統按下述步驟進行檢查:

①如果Requesti[j] <= Need[i, j],便轉向步驟②;否則認為出錯,因為它所需要的資源數已超過它所宣佈的最大值。

②如果Requesti[j] <= Available[j],便轉向步驟③;否則,表示尚無足夠資源,Pi須等待。

③系統試探著把資源分配給程序Pi,並修改下面資料結構中的數值:
  1. Available[j] = Available[j] - Requesti[j];
  2. Allocation[i, j] = Allocation[i, j] + Requesti[ j];
  3. Need[i, j] = Need[i, j] - Requesti[j];

④系統執行安全性演算法,檢查此次資源分配後,系統是否處於安全狀態。若安全,才正式將資源分配給程序Pi,以完成本次分配;否則,將本次的試探分配作廢,恢復原來的資源分配狀態,讓程序Pi等待。

3) 安全性演算法
①設定兩個向量。工作向量Work;它表示系統可提供給程序繼續執行所需的各類資源數目,它含有所個元素,在執行安全演算法開始時,Work=Available; Finish:它表示系統是否有足夠的資源分配給程序,使之執行完成。開始時 Finish[i]=false;當有足夠資源分配給程序 Pi 時,再令 Finish[i]=true。

②從程序集合中找到一個能滿足下述條件的程序:Finish[i]=false;    Need[i, j]<=Work[j]; 若找到,執行下一步驟,否則,執行步驟4。

③當程序Pi獲得資源後,可順利執行,直至完成,並釋放出分配給它的資源,故應執行:
  1. Work[j]=Work[j]+Allocation[i, j];
  2. Finish[i]=true;
  3. go tostep <2>;

④如果所有程序的Finish[i]=tme都滿足,則表示系統處於安全狀態;否則,系統處於不安全狀態。

3. 銀行家演算法舉例

假定系統中有5個程序{P0, P1, P2, P3, P4}和三類資源{A, B, C},各種資源的數量分別為10、5、7,在T0時刻的資源分配情況見表2-16。

1) T0時刻的安全性。
利用安全性演算法對T0時刻的資源分配進行分析,由表2-17可知,在T0時刻存在著一個安全序列{P1, P3, P4, P2, P0},故系統是安全的。

表2-16 T0時刻的資源分配
程序 / 資源情況 Max
A  B  C
Allocation
A  B  C
Need
A  B  C
Available
A  B  C
P0 7  5  3 0  1  0 7  4  3 3  3  2
(2  3  0)
P1 3  2  2 2  0  0
(3  0  2)
1  2  2
(0  2  0)
P2 9  0  2 3  0  2 6  0  0
P3 2  2  2 2  1  1 0  1  1
P4 4  3  3 0  0  2 4  3  1

表2-17 T0時刻的安全序列
程序 / 資源情況 Work
A  B  C
Need
A  B  C
Allocation
A  B  C
Work+Allocation
A  B  C
Finish
P1 3  3  2 1  2  2 2  0  0 5  3  2 true
P3 5  3  2 0  1  1 2  1  1 7  4  3 true
P4 7  4  3 4  3  1 0  0  2 7  4  5 true
P2 7  4  5 6  0  0 3  0  2 10  4  7 true
P0 10  4  7 7  4  3 0  1  0 10  5  7 true

2) P1請求資源
P1發出請求向量Request1(l,, 0, 2),系統按銀行家演算法進行檢查:
  • Request1(1, 0, 2) <= Need1(l, 2, 2)。
  • Request1(1, 0, 2) <= Available1(3, 3, 2)。
  • 系統先假定可為P1分配資源,並修改Available、Allocation1和Need1向量,由此形成的資源變化情況見表2-18。
  • 再利用安全性演算法檢查此時系統是否安全。

表2-18 P1申請資源時的安全性檢測
程序 / 資源情況 Work
A  B  C
Need
A  B  C
Allocation
A  B  C
Work+ Allocation
A  B  C
Finish
P1 2  3  0 0  2  0 3  0  2 5  3  2 true
P3 5  3  2 0  1  1 2  1  1 7  4  3 true
P4 7  4  3 4  3  1 0  0  2 7  4  5 true
P0 7  4  5 7  4  3 0  1  0 7  5  5 true
P2 7  5  5 6  0  0 3  0  2 10  5  7 true

3) P4請求資源
P4發出請求向量Request4(3, 3, 0),系統按銀行家演算法進行檢查:
  • Request4(3, 3, 0) <= Need4(4, 3, 1)。
  • Request4(3, 3, 0) > Available(2, 3, 0),讓 P4 等待。

4) P0請求資源
P0發出請求向量Request0(0, 2, 0),系統按銀行家演算法進行檢查:
  • Request0(0, 2, 0) <= Need0(7, 4, 3)。
  • Request0(0, 2, 0) <= Available(2, 3, 0)。
  • 系統暫時先假定可為P0分配資源,並修改有關資料,見表2-19。

表2-19 為P0分配資源後的有關資源資料
程序 / 資源情況 Allocation
A  B  C
Need
A  B  C
Available
A  B  C
P0 0  3  0 7  2  3 2  1  0
P1 3  0  2 0  2  0
P2 3  0  2 6  0  0
P3 2  1  1 0  1  1
P4 0  0  2 4  3  1

5) 進行安全性檢測。
可用資源Available(2, 1, 0)已不能滿足任何程序的需要,故系統進入不安全狀態,此時系統不分配資源