背景簡介:
在銀行中,客戶申請貸款的數量是有限的,每個客戶在第一次申請貸款時要聲明完成該項目所需的最大資金量,在滿足所有貸款要求時,客戶應及時歸還。銀行家在客戶申請的貸款數量不超過自己擁有的最大值時,都應儘量滿足客戶的需要。在這樣的描述中,銀行家就好比操作系統,資金就是資源,客戶就相當於要申請資源的進程。
銀行家算法是一種最有代表性的避免死鎖的算法。在避免死鎖方法中允許進程動態地申請資源,但系統在進行資源分配之前,應先計算此次分配資源的安全性,若分配不會導致系統進入不安全狀態,則分配,否則等待。爲實現銀行家算法,系統必須設置若干數據結構。
安全序列是指一個進程序列{P1,…,Pn}是安全的,即對於每一個進程Pi(1≤i≤n),它以後尚需要的資源量不超過系統當前剩餘資源量與所有進程Pj (j < i )當前佔有資源量之和。(即在分配過程中,不會出現某一進程後續需要的資源量比其他所有進程及當前剩餘資源量總和還大的情況)
注:存在安全序列則系統是安全的,如果不存在則系統不安全,但不安全狀態不一定引起死鎖。
原理過程:
系統給當前進程分配資源時,先檢查是否安全:
在滿足當前的進程X資源申請後,是否還能有足夠的資源去滿足下一個距最大資源需求最近的進程(如某進程最大需要5個單位資源,已擁有1個,還尚需4個),若可以滿足,則繼續檢查下一個距最大資源需求最近的進程,若均能滿足所有進程,則表示爲安全,可以允許給當前進程X分配其所需的資源申請,否則讓該進程X進入等待。
(注:檢查過程中,每擬滿足一個進程,則進行下個檢查時,當前可用資源爲回收上一個進程資源的總值,每滿足一個進程表示此進程已結束,資源可回收。)
如圖:
算法過程:
Available[ ]矩陣數組表示某類資源的可用量
Claim[ i ][ j ]表示進程Pi最大需要Rj類資源的數量
Allocation[ i ][ j ]表示Pi已佔有的Rj類資源數量
Need[ i ][ j ]表示Pi尚需Rj類資源的數量
-------------------------------------------------------------------
Need[ i ][ j ]=Claim[ i ][ j ]—Allocation[ i ][ j ]
-------------------------------------------------------------------
Request[ i ]表示進程Pi進程的申請向量,如 Request[ i ][ j ]=m 表示Pi申請m個Rj類資源
對於當前進程Pi X
(1) 檢查if( Request[ i ][ j ]<=Need[ i ][ j ] ) goto (2)
else error(“進程 i 對資源的申請量大於其說明的最大值 ”);
(2) 檢查 if ( Request[ i ][ j ]<=Available[ j ] ) goto (3)
else wait() ; /*注意是等待!即在對後續進程的需求資源判斷中,若出現不符合的則安全檢查結束,當前進程進入等待*/
(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) 安全檢查,若檢查結果爲安全,則(3)中執行有效,否則分配作廢,使該Pi進程進入等待
檢查算法描述:
向量Free[ j ]表示系統可分配給各進程的Rj類資源數目,初始與當前Available等值
向量Finish[ i ]表示進程Pi在此次檢查中是否被滿足,初始均爲false 當有足有資源可分配給進程時,
Finish[ i ]=true, Pi完成並釋放資源(Free[ j ]+=Allocation[ i ][ j ])
1) 從進程隊列中找一個能滿足下述條件的進程Pi
①、Finish[ i ]==false,表示資源未分配給Pi進程
②、Need[ i ][ j ]<Free[ j ],表示資源足夠分配給Pi進程
2) 當Pi獲得資源後,認爲Pi完成,釋放資源
Free[ j ]+=Allocation[ i ][ j ];
Finish[ i ]=true;
goto Step 1);
例:
int trueSum=0, i=0 ; boolean Flag=true;
while( trueSum<P.length-1 && Flag==true ){
i=i%P.length;
if( Finish[ i ]==false ){
if(Need[ i ][ j ]<Free[ j ]){
Free[ j ]+=Allocation[ i ][ j ];
Finish[ i ]=true;
trueSum++;
i++;
}else{
Flag=false;
}
} }
if( Flag==false)
檢查不通過,拒絕當前進程X的資源申請
else
檢查通過,允許爲當前進程X分配資源
即若可達到Finish[ 0,1,2,......n ] ==true 成立則表示系統處於安全狀態
例:
有5個進程{P1,P2,P3,P4,P5} 。4類資源{R1,R2,R3,R4} 各自數量爲6、3、4、2
T0時刻各進程分配資源情況如下
T0時刻爲安全狀態,存在安全序列{P4,P1,P2,P3,P5} 如下:
(銀行家算法在避免死鎖角度上非常有效,但是需要在進程運行前就知道其所需資源的最大值,且進程數也通常不是固定的,因此使用有限,但從思想上可以提供瞭解,可以轉換地應用在其他地方)