銀行家算法是資源和死鎖避免的算法,由艾茲格·迪傑斯特拉(Edsger Dijkstra) 設計的算法用於測已確定總數量的資源分配的安全性,在決定是否該分配應該被允許並進行下去之前,通過“s-state”校驗碼測試資源分配活動期間產生死鎖條件的可能性。
該算法是為為THE操作系統設計並且最在在EWD108描述。當一個新的進程進入系統時,進程必須聲明所需每個資源實例最大的數量和類型。顯然,資源數量不不能超過系統最大的資源數。與此同時,進程獲得的資源必須在有限的時間內釋放。
資源
對於銀行家算法的實現,需要知道三件事:
- 每個進程所能獲取的每種資源數量是多少[MAX]
- 每個進程當前所分配到的每種資源的數量是多少[ALLOCATED]
- 系統當前可分配的每種的資源數量是多少[AVAILABLE]
只有當資源滿足以下條件,資源才會被分配:
- request <= max, 也可設置錯誤條件,當進程所請求的資源超過最大的要求
- request <= available, 或者進
程一直等直到資源可分配
一些資源在實際的系統被跟蹤,如:內存,信號量以及接口。
銀行家算法名字源於該算法實際上是用於確保銀行系統不會用盡系統資源,因為當銀行系統不再滿足所有客戶的需求,系統將不會分配錢(看作資源)給客戶,銀行必須確保對錢的請求不會導致銀行系統處於不安全狀態。如果上述情況不會發生,則該情況下請求是被允許的,否則,客戶必須等到其他客戶往銀行存進足夠銀行分配的資金。
基本數據結構用於維護運行銀行家算法:
用n表示系統資源數量,m表示系統資源類型。則我們需要以下的數據結構:
- Available: 長度為m的向量用來表示每種資源可分配的數量。如果available[j]=k, 資源類型為Rj可分配數量為k。
- Max: n * m矩陣,定義,每個進程最大的資源需求。如果Max[i,j]=k. 表明Pi對類型為Rj資源的請求為k.
- Allocation: n * m矩陣定義每個進程已分配到的每種資源的數量。如果Allocation[i,j] = k,進程Pi已分配到類型為Rj的資源數量為k。
- Need: n * m 矩陣表明每個進程所需的資源數量,如果Need[i,j] = k, 進程Pi需要至少得到k數量的資源Rj,才能完成任務。
公式:Need[i,j] = Max[i,j] - Allocation[i,j]
例子:
系統資源總數:
A B C D
6 5 7 6系統可分配資源數:
A B C D
3 1 1 2進程 (當前分配到的資源數):
A B C D
P1 1 2 2 1
P2 1 0 3 3
P3 1 2 1 0進程 (最大資源需求數):
A B C D
P1 3 3 2 2
P2 1 2 3 4
P3 1 3 5 0Need= Max - Allocation
進程 (需要的資源數):
A B C D
P1 2 1 0 1
P2 0 2 0 1
P3 0 1 4 0
安全和不安全狀態
如果該狀態下所有進程都可以結束運行,則該狀態是安全。因為系統無法知道什么時候一個進程結束運行,或有多少資源被進程請求,系統只是假設所有的進程最終會試圖獲取他們所規定的最大資源,並且在獲得資源使用完之后會結束運行。在大多數的情況下,該假設是很合理的,因為系統不會特別的關心每個進程的運行多久(至少不是從死鎖避免的角度)。
對於該猜想,算法確定是否一個狀態是安全通過找到一個猜想性的進程請求序列,允許所有進程獲取最大的資源數並順利結束運行。而任何無法達到上訴要求的的狀態都是不安全的狀態。
我們可以得到之前例子的安全狀態,只要能使每個進程獲得最大資源並結束運行。
1.P1 得到 2 A,1 B 和 1 D,達到進程需求的最大資源數
- [可分配資源:<3 1 1 2> - <2 1 0 1> = <1 0 1 1>]
- 系統當前有1 A, 0 B, 1 C, 和 1 D 資源可分配
2.P1 結束運行,釋放3 A, 3 B, 2 C, 和2 D資源給系統。
- [可分配資源:<1 0 1 1> + <3 3 2 2> = <4 3 3 3>]
- 系統當前有4 A, 3 B, 3 C, 和 3 D 資源可分配
3.P2 結束運行,請求0 A, 2 B, 0 C, 和1 D資源,之后運行結束,釋放資源給系統
- [可分配資源:<4 3 3 3> - <0 2 0 1> + <1 2 3 4>= <5 3 6 6>]
- 系統當前有5 A, 3 B, 6 C, 和 6 D 資源可分配
4.P3 請求0 A, 1 B, 4 C, 和0 D資源,之后運行結束,釋放資源給系統
- [可分配資源:<5 3 6 6> - <0 1 4 0> + <1 3 5 0>= <6 5 7 6>]
- 系統現在用所有的資源6 A, 5 B, 7 C 和 6 D
5.由於所有的進程可以結束運行,該狀態是安全的狀態。
請求
當系統收到對資源請求信號時,系統運行銀行家算法判斷允許請求是否安全。
1.該請求是否可以運行?
如果不允許,該請求則是不可行的,必須要么拒絕請求或插入到等待隊列。
2.假設請求被允許
3.是否安全?
如果安全,請求授予
否則,要么拒絕或插入到等待隊列
不論系統拒絕請求或請求延遲或不安全請求都是系統的特殊決定。
例子:
從之前的例子開始,假設進程3請求2個單位的資源C。
1. 系統沒有足夠的資源C可以用於分配
2. 該請求被拒絕另一方面,假設進程3請求1單元資源C。
1. 系統有足夠的資源分配
2. 請求允許
新的狀態如下:系統可分配的資源
A B C D
Free 3 1 0 2
進程 (當前進程分配到資源):
A B C D
P1 1 2 2 1
P2 1 0 3 3
P3 1 2 2 0
進程(最大需求資源數):
A B C D
P1 3 3 2 2
P2 1 2 3 4
P3 1 3 5 0
- 判斷是新的安全狀態是否安全
1>P1 獲得2 A,1 B, 和 1 D資源並運行結束
2>之后,P2 能獲得2 B 和1 D資源並結束運行
3>最后P3 能獲得1 B 和3 C資源並運行結束
4>因此,改新狀態為安全的
最后,從該狀態開始,假設進程2請求1單元的資源B。
1.系統有足夠的資源
2.假設所有的請求都允許,新狀態如下:
系統可分配的資源:
A B C D
Free 3 0 1 2
進程 (當前進程分配到資源):
A B C D
P1 1 2 2 1
P2 1 1 3 3
P3 1 2 1 0
進程(最大需求資源數):
A B C D
P1 3 3 2 2
P2 1 2 3 4
P3 1 3 5 0
1.存在安全的狀態嗎?假設P1,P2,P3請求資源B 和 C。
P1無法完成資源B的請求
P2無法完成資源B的請求
P3無法完成資源B的請求
沒有進程能獲得足夠的資源結束運行,故該狀態是不安全的。
同其他的算法相似,銀行家算法運行時也有一些局限。特別是,必須知道每個進程所能請求的資源。在大多數系統,該信息是不可知的,使的無法順利運行銀行家算法。而且也無法去假設進程數量是不變的,因為大多數的系統的進程數量是動態變化的。再者,對於正確的算法,進程會釋放其全部的資源(當進程結束運行),然而對於實際中的系統則是不可行。為了資源的釋放等上數小時甚至幾天,通常是不可接受的。