//銀行家算法
/**
* 作者:老謝
* 最后修改日期:2006,4,21
* Email:do_while@sohu.com
* 功能:銀行家算法實現
**/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define M 5 /*進程數*/
#define N 3 /*資源數*/
/**
* TC中用到
#define true 1
#define false 0
typedef int bool
**/
//系統可用資源向量
int Available[N] = {3,3,2};
//最大需求向量
int Max[M][N] = {
{7,5,3},
{3,2,2},
{9,0,2},
{2,2,2},
{4,3,3},
};
//資源分配向量
int Allocation[M][N] = {
{0,1,0},
{2,0,0},
{3,0,2},
{2,1,1},
{0,0,2},
};
//需求向量
int Need[M][N] = {
{7,4,3},
{1,2,2},
{6,0,0},
{0,1,1},
{4,3,1},
};
//比較兩個一維數組
//判斷 a >= b ?
bool compare(int *a,int *b,int n)
{
int i=0;
for(i = 0;i < n;i++)
{
if(a[i] < b[i])
{
return false;
}
}
return true;
}
//一維數組加法
//a = a + b
void add(int *a,int *b,int n)
{
int i = 0;
for(i = 0;i < n;i++)
{
a[i] += b[i];
}
}
//一維數組減法
//a = a - b
void subtract(int *a,int *b,int n)
{
int i = 0;
for(i = 0;i < n;i++)
{
a[i] -= b[i];
}
}
//將數組b的值賦給a,n為數組的大小
void assign(int *a,int *b,int n)
{
int i = 0;
for(i = 0;i < n;i++)
{
a[i] = b[i];
}
}
//判斷是否是安全狀態
//av 可用資源矩陣
//sl 記錄安全路徑
bool safe(int *sl)
{
int i;
int count = 0; /*記錄finish[i] = true 的個數*/
int n = 0;
int work[N];
bool finish[M];
//work = av;
assign(work,Available,N);
//初始化標記 finish
for(i = 0;i < M;i++)
{
finish[i] = false;
}
//n為進程的個數
//循環最多執行n次
n = M;
while(n--)
{
for(i = 0;i < M;i++)
{
//判斷是否安全
if(count >= M)
{
//全部進程都可安全執行(finish = true)
return true;
}
//判斷能否滿足進程i的要求
//work >= Need[i] ?
if(finish[i] == false && compare(work,Need[i],N))
{
//分配,待進程完成后再釋放
add(work,Allocation[i],N);
finish[i] = true;
//記錄安全路徑
sl[count] = i;
//能滿足的進程數+1
count++;
}
}
}
if(count >= M)
{
return true;
}
else
{
return false;
}
}
//請求分配
//pid進程,r請求向量,n資源個數
bool request(int pid,int * r,int n)
{
int i;
//記錄安全路徑
int sl[5];
if(compare(Need[pid],r,n) == true &&
compare(Availavle,r,n))
{
//嘗試分配資源
subtract(Available,r,N);
add(Allocation[pid],r,N);
subtract(Need[pid],r,N);
//判斷是否是安全狀態
if(safe(sl))
{
//打印安全路徑
printf("安全路徑:/n/t");
for(i = 0;i < M;i++)
{
printf("p%d ",sl[i]);
}
printf("/n");
//可以分配
return true;
}
else
{
//不分配
//恢復到分配前的狀態
add(Available,r,N);
subtract(Allocation[pid],r,N);
add(Need[pid],r,N);
return false;
}
}
else
{
//error
return false;
}
}
//打印一維數組
void print(int *a,int n)
{
int i;
for(i = 0;i < n;i++)
{
printf("%4d",a[i]);
}
printf("/n");
}
//提示信息
char help()
{
printf("-----操作提示-----/n");
printf("A--自動隨機申請資源/n");
printf("S--手動輸入申請資源/n");
return getch();
}
//顯示系統信息
void init()
{
int i;
printf("該系統共有進程5個,/n其對資源的需求和分配情況分別是:/n");
for(i = 0;i < M;i++)
{
printf("/t進程%d資源最大需求:",i);
print(Max[i],N);
}
printf("/n");
for(i = 0;i < M;i++)
{
printf("/t進程%d已經分配資源:",i);
print(Allocation[i],N);
}
printf("系統可用資源數量:/n/t");
print(Available,N);
}
//輸入
void input(int *r,int n,int *id)
{
char ch;
printf("請輸入進程的id(0 ~ 4):/n");
ch = getche();
*id = ch - 0x30;
printf("/n請輸入對0類資源的申請數量(int):/n");
ch = getche();
r[0] = ch - 0x30;
printf("/n請輸入對1類資源的申請數量(int):/n");
ch = getche();
r[1] = ch - 0x30;
printf("/n請輸入對2類資源的申請數量(int):/n");
ch = getche();
r[2] = ch - 0x30;
printf("/n您輸入的是:Request[%d](%d,%d,%d)/n",*id,r[0],r[1],r
[2]);
}
//檢查輸入
bool check(int id,int r1,int r2,int r3)
{
if(id > 4 || id < 0 || r1 < 0 || r2 < 0 || r3 < 0)
{
return false;
}
else
{
return true;
}
}
int main()
{
//進程id
int id;
//控制字符
char control;
//資源請求向量
int r[3];
//顯示開始信息
init();
//隨機數初始化
srand(NULL);
//主控過程
while(1)
{
//提示
control = help();
if(control == 'a' || control == 'A')
{
//隨機申請資源
id = rand()%5;
r[0] = rand()%5;
r[1] = rand()%5;
r[2] = rand()%5;
//顯示申請信息
printf("/tRequest[%d](%d,%d,%d)/n",id,r[0],r[1],r[2]);
if(request(id,r,N))
{
printf("分配成功!/n");
}
else
{
printf("分配失敗!/n");
}
}
else
{
//輸入申請信息
input(r,N,&id);
//檢查輸入
if(check(id,r[0],r[1],r[2]) == false)
{
printf("/n輸入錯誤請檢查后重新輸入/n");
continue;
}
//執行
if(request(id,r,N))
{
printf("Request Secceed!/n");
}
else
{
printf("Request Fail!/n");
}
}
//顯示當前系統資源和進程情況
printf("系統可用資源:/n");
print(Available,N);
printf("進程%d的最大資源需求:/n",id);
print(Max[id],N);
printf("進程%d已經分配資源:/n",id);
print(Allocation[id],N);
//提示是否繼續n或N退出
printf("/nContinue?(Y/N)!/n");
control = getch();
if(control == 'n' || control == 'N')
{
break;
}
}
return 0;
}