挑戰408——作業系統(14)——銀行家演算法與死鎖解除
回顧之前提到的死鎖的解決方式:預防,檢測,避免。避免死鎖的方式中最著名的就是銀行家演算法了。不過在介紹之前,先引入一段介紹。
死鎖的避免
安全序列
產生死鎖的原因有很多,資源不足還有程序推進次序非法,都是原因。但是系統有不可能一下子滿足所有程序的資源請求,才會產生死鎖的危險。我們知道,程序結束以後是會釋放資源的,釋放的資源也是可以給後面的程序使用的。我們可以回顧一下哲學問題,我們的那種作法其實就是,當他們同時餓的時候,我們強制選出其中一位來先吃,吃完後釋放筷子,這樣也就不會有餓死的危險。如果按吃飯的優先順序標號,那麼按照優先順序來排序,最後一定是可以所有的哲學家都有飯吃。(雖然這道題的序列是任意的)。於是我們定義這樣一個概念: 如果一組程序,按照<P1,P2,P3,P4,…Pn>的次序執行,併為它們分配資源,如果都每個程序都能順利執行,那麼就稱這個序列為一個安全序列。否則就是一個不安全序列。
銀行家演算法
銀行家演算法主要分為兩部分,安全檢測和資源請求部分。該演算法主要有四大資料結構: 下面簡要介紹一下: Resource:系統中的資源總量 Available:系統中尚未分配的,可以使用的資源量 Need:每個程序對每種資源的最大需求量。(一行代表某個程序,一列代表某種資源) Allocation:目前已經分配的情況
安全檢測
若在資源請求的時候,本次的請求超過了它最初的資源要求總量,那麼該程序就會因為總資源數不足
資源分配演算法
下面用一個例項來說明銀行家演算法的實現:
如圖,系統中有三種資源R1,R2,R3,總量分別是9,3,6。當前已經將他們分配給了4個程序,問是否存在一個安全序列P,使得這組程序在執行期間處於安全狀態?
由前面的兩個矩陣和總資源數,很容易算出可供分配的資源數為(0,1,1).於是我們就可以分析一下該演算法的過程了:
- 首先我們先按順序,將所有的可分配資源分配給P1,得出此時P1的資源數(左邊),和P1的最大資源需求數(右邊的need)。發現此時p1的資源不足以讓執行,於是不分配給p1,讓它暫時掛起,繼續判斷:
- 接著我們按順序,把所有的資源分配給P2,這個時候分配的資源數已經足夠滿足need矩陣了,程式順利執行,然後退出的時候將所佔有的資源全部釋放,此時Available(可用資源數)增加,增加的量就是原P2所佔有的量,從解題步驟來看,Available的數值就是我們之前假設的把所有資源都加在P2那時候的狀態。
- 此時因為資源增加了,可以將之前的P1再分配資源看看夠不夠,或者直接向下給P3分配。都可以,不過推薦第一種方式,因為怕遺漏。
- 然後重複上面的操作,如果始終有某個程序不能滿足,那麼就不存在安全狀態,否則全部程式能按此順序完成,這就是安全狀態。
我們發現,按照剛剛執行的順序,<P2 -> P1->P3 ->P4>,那麼這組程序一定不會發生死鎖,也就是我們說的安全序列。當然上面的P3和P1的順序調換,也是安全序列。所以,安全序列有可能不止一個。 到了最後的程序退出的時候,注意到Available的值一定等於總資源數。
死鎖的解除
那麼如果死鎖一旦發生了呢?那就得解除這個狀態。我們一般有一下方式:
- 撤銷死鎖程序
- 剝奪死鎖程序的資源,直到不存在死鎖
- 鴕鳥演算法(即直接忽略,當做什麼都沒發生,絕大多數的作業系統選擇這個方法)。