【作業系統】銀行家演算法實現(C語言)
注意:本人編碼水平很菜。算是自己的一個總結。可能會有我還沒有發現的bug。如果有人發現後可以指出,不勝感激。
1.銀行家演算法:
我們可以把作業系統看作是銀行家,作業系統管理的資源相當於銀行家管理的資金,程式向作業系統請求分配資源相當於使用者向銀行家貸款。
為保證資金的安全,銀行家規定: (1) 當一個顧客對資金的最大需求量不超過銀行家現有的資金時就可接納該顧客; (2)
顧客可以分期貸款,但貸款的總數不能超過最大需求量; (3)
當銀行家現有的資金不能滿足顧客尚需的貸款數額時,對顧客的貸款可推遲支付,但總能使顧客在有限的時間裡得到貸款; (4)
當顧客得到所需的全部資金後,一定能在有限的時間裡歸還所有的資金.
作業系統按照銀行家制定的規則為程式分配資源,當程式首次申請資源時,要測試該程式對資源的最大需求量,如果系統現存的資源可以滿足它的最大需求量則按當前的申請量分配資源,否則就推遲分配。當程式在執行中繼續申請資源時,先測試該程式本次申請的資源數是否超過了該資源所剩餘的總量。若超過則拒絕分配資源,若能滿足則按當前的申請量分配資源,否則也要推遲分配。 ---------引用自百度百科
2.簡單來說:系統中的資源是有限的。不足以一下子把所有程式所需的資源都分配。
我們需要做的就是在有限的資源下,是否有一個分配順序,可以使得全部程式都可以獲得資源並執行,如果可以則返回一個安全佇列,如果不可以,則說明有風險,系統可能會陷入死鎖。
3.資料結構
1)可利用資源向量Available
是個含有m個元素的陣列,其中的每一個元素代表一類可利用的資源數目。如果Available[j]=K,則表示系統中現有Rj類資源K個。
2)最大需求矩陣Max
這是一個n×m的矩陣,它定義了系統中n個程式中的每一個程式對m類資源的最大需求。如果Max[i,j]=K,則表示程式i需要Rj類資源的最大數目為K。
3)分配矩陣Allocation
這也是一個n×m的矩陣,它定義了系統中每一類資源當前已分配給每一程式的資源數。如果Allocation[i,j]=K,則表示程式i當前已分得Rj類資源的
數目為K。 4)需求矩陣Need。
這也是一個n×m的矩陣,用以表示每一個程式尚需的各類資源數。如果Need[i,j]=K,則表示程式i還需要Rj類資源K個,方能完成其任務。
4.舉個例子:
系統總資源是(9,3,6)
max | Allocation | need | Available | finished | |
---|---|---|---|---|---|
R1 R2 R3 | R1 R2 R3 | R1 R2 R3 | R1 R2 R3 | ||
p1 | 3 , 2 , 2 | 1 ,0 ,0 | 2 , 2 , 2 | 6,1,4 (9,3,6) | True |
p2 | 6 ,1 ,3 | 5 ,1 ,2 | 1 , 0 ,1 | 0,1,0 (6,2,3) | True |
p3 | 3 ,1 ,4 | 2 , 1 , 1 | 1 ,0 , 3 | 5,2,0 (8,3,4) | Ture |
p4 | 4 ,2 , 2 | 0 ,0, 2 | 4 ,2 ,0 | 4,1,4 (8,3,6) | True |
分配給p2(1,0,1) 目前系統可用資源 1,1,1
1.此時p2仍然需要1,0,1 ,可以滿足p2所需資源 。p2完成後釋放資源
此時系統資源總數為(6,2,3)
2.分配給p3,系統資源剩(5,2,0)。p3完成後釋放資源,
此時的資源總數為(8,3,4)
3.分配給p4,系統資源剩(4,1,4)。P4完成後釋放資源,此時系統資源總數為(8,3,6)
4.分配給p1,系統資源(6,1,4),p1完成後釋放資源,此時系統資源總數為(9,3,6)
全部程式執行完畢。
安全序列為:p2---->p3--->p4---->p1
執行截圖 :
5.程式碼段
#include<stdio.h>
#include<stdlib.h>
#define Num_Dev 3 // 每個程式所需的裝置的種類數量
#define Max 10 //可容納的最多的程式數量
int Max_Need_Dev [Max][Num_Dev]; //所有程式所需要的裝置的最大數目
int Allocation_Dev [Max][Num_Dev]; //所有程式已經分配到的裝置的數目
int Need_Dev [Max][Num_Dev]; //所有程式還需要的裝置的數目
int current_Available_Dev[Max][Num_Dev]; //記錄分配完之後,此時系統的可用資源數目(因為假如會產生安全佇列,那麼有多少個程式就會產生多少次這樣的當前分配後的可用資源數目)
int current_recycle_Dev[Max][Num_Dev]; //記錄回收完之後,系統中各個裝置的數目
int system_Dev[Num_Dev]; //系統中所擁有的各類裝置的數量
int Available_Dev [Num_Dev]; //系統中剩餘的資源數量
int finish [Max]; //存存放所有程式是否已經執行完畢。
int quene[Max]; //假設不會出現死鎖,那麼用於存放安全佇列。 即記錄每個程式的下表。
int num; // 程式的名字
void init(){
printf("請輸入系統中各類資源的數目總和:\n");
for (int i = 0; i < Num_Dev; i++)
{
scanf("%d",&system_Dev[i]);
Available_Dev[i] = system_Dev[i];
printf("%d\t",Available_Dev[i]);
}
printf("\n");
printf("請輸入程式的數量:\n");
scanf("%d",&num);
printf("\n");
printf("請輸入各個程式執行所需要全部裝置的數量:\n");
for(int i = 0;i < num; i ++){
for (int j = 0; j < Num_Dev; j++)
{
scanf("%d",&Max_Need_Dev[i][j]);
}
}
printf("\n");
printf("請輸入各個程式已經分配到的裝置的數目:\n");
for(int i = 0;i < num; i ++){
for (int j = 0; j < Num_Dev; j++)
{
scanf("%d",&Allocation_Dev[i][j]);
Available_Dev[j] = Available_Dev[j] - Allocation_Dev[i][j]; //計算系統中剩餘裝置的數目
}
}
printf("\n");
for(int i = 0;i < num; i ++){
for (int j = 0; j < Num_Dev; j++)
{
Need_Dev[i][j] = Max_Need_Dev[i][j] - Allocation_Dev[i][j]; //計算各個程式依然所需要的各個裝置的數目
}
}
for (int i = 0; i < num; i++)
{
finish[i] = 0;
quene[i] = -1;
}
}
void print(){
printf("程式ID\t|\tMax\t|\tAllocat\t|\tNeed\t|\tAvail\t|\t\tfinish\n");
for (int i = 0; i < num; i++)
{
printf("%d\t|\t",quene[i]);
printf("%d,%d%,%d\t|\t%d,%d%,%d\t|\t%d,%d%,%d\t|\t%d,%d%,%d (%d,%d,%d)\t|\t%d\\",Max_Need_Dev[i][0],Max_Need_Dev[i][1],Max_Need_Dev[i][2],Allocation_Dev[i][0],Allocation_Dev[i][1],Allocation_Dev[i][2],Need_Dev[i][0],Need_Dev[i][1],Need_Dev[i][2],current_Available_Dev[i][0],current_Available_Dev[i][1],current_Available_Dev[i][2],current_recycle_Dev[i][0],current_recycle_Dev[i][1],current_recycle_Dev[i][2],finish[i]);
printf("\n");
}
}
int conpare(int *p){ //判斷當前可用裝置的數目是否可以滿足所傳入的程式的要求
for(int j = 0;j < Num_Dev; j ++){
if(*(p+j) > Available_Dev[j] ){
return 0;
}
}
return 1;
}
void recycle(int *p){ //若一個程式執行完畢,回收已經分配給它的裝置
for (int i = 0; i < Num_Dev; i++)
{
Available_Dev[i] += *(p+i);
}
}
int allocation(){
int flag = 0;
int count = 1; //判斷死鎖。就是遍歷一遍之後沒有程式可以執行。
int i = 0; //判斷是哪一個程式
int index = 0; //用於記錄安全佇列的下表
int max_times; //因為有num個變數, 所以假如有安全佇列,最多就是尋找num的平方次
while (1)
{
max_times ++;
if(conpare(Need_Dev[i])==1&&finish[i] == 0){
count = 0;
finish[i] = 1; //表示該程式獲得資源後執行完畢
for (int j = 0; j < Num_Dev; j++) // 讓程式獲取剩餘裝置 即
{
Allocation_Dev[i][j] += Need_Dev[i][j]; //1.讓程式已經分配的裝置數目加上它仍然需要的
Available_Dev[j] -= Need_Dev[i][j]; //2.系統中目前可用的裝置數目減去程式需要的
current_Available_Dev[i][j] = Available_Dev[j]; //記錄分配完之後,此時系統的可用資源數目(因為假如會產生安全佇列,那麼有多少個程式就會產生多少次這樣的當前分配後的可用資源數目)
}
recycle(Max_Need_Dev[i]); // 回收資源
for (int j = 0; j < Num_Dev; j++)
{
current_recycle_Dev[i][j] += Available_Dev[j];
}
quene[index] = i;
index ++;
if(index == num ){
flag = 1;
printf("安全佇列已經返回了。快去看看吧!\n");
break;
}
}
if(count == num){
printf("會發生死鎖。無安全佇列。。。。。。\n");
break;
}
if(i == num - 1){
i = 0;
continue;
}
if(max_times == num*num){
printf("全部可能已經執行完畢,無安全佇列。。。。。。\n");
break;
}
count ++;
i ++;
}
return flag;
}
int main(void ){
init();
int flag = allocation();
print();
if(flag == 1){
for (int i = 0; i < num; i++)
{
printf("%d--->",quene[i]);
}
}
printf("\n");
system("pause");
}