//WMF课程设计源代码(半自动银行家算法)
#include<stdlib.h> //包含随机函数的头文件
#include<stdio.h>
//全局变量
int n; //进程数
int m; //资源种类数
int h; //请求资源的进程
int available[502]; //可利用资源向量
int available1[502]; //存储初始可利用资源向量
int max[102][502]; //最大需求矩阵
int allocation[102][502]; //分配矩阵
int allocation1[102][502]; //存储初始分配矩阵
int need[102][502]; //需求矩阵
int need1[102][502]; //存储初始需求矩阵
int request[102][502]; //进程的请求向量
int work[502]; //系统可提供给进程继续运行的各类资源数目
int finish[102]; //是否有足够的资源分配给进程,值为1表示是,值为0表示否
int xulie[102]; //安全序列
int i,j;
void resource(); //查看现有数据结构的信息
void show(); //作者信息及其相关简介
void request1(); //银行家算法
bool safe(); //安全性算法
void AI();
void main()
{
/*****************************初始操作**************************/
show();
printf("请输入进程数:");
scanf("%d",&n);
printf("请输入资源种类数:");
scanf("%d",&m);
printf("请输入各进程对各资源的最大需求数:\n");
for(i=0;i<n;i++)
for(j=0;j<m;j++)
scanf("%d",&max[i][j]);
printf("请输入各进程已分配的资源数:\n");
for(i=0;i<n;i++)
for(j=0;j<m;j++)
scanf("%d",&allocation[i][j]);
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
need[i][j]=max[i][j]-allocation[i][j];
if(need[i][j]<0)
{
printf("%d号进程分配的%d类资源出现错误,请重新输入。\n",i+1,j+1);
printf("请输入各进程对各资源的最大需求数:\n");
for(i=0;i<n;i++)
for(j=0;j<m;j++)
scanf("%d",&max[i][j]);
printf("请输入各进程已分配的资源数:\n");
for(i=0;i<n;i++)
for(j=0;j<m;j++)
scanf("%d",&allocation[i][j]);
}
}
}
printf("请输入各资源的现有数目:\n");
for(i=0;i<m;i++)
scanf("%d",&available[i]);
for(i=0;i<m;i++) //存储初始量
available1[i]=available[i];
for(i=0;i<n;i++)
for(j=0;j<m;j++)
need1[i][j]=need[i][j];
for(i=0;i<n;i++)
for(j=0;j<m;j++)
allocation1[i][j]=allocation[i][j];
//想查看现有数据结构的信息吗?(N:不用)
resource();
safe(); //安全性算法
request1(); //银行家算法
}
void show()
{
printf("WMF 之银行家算法半手工版!\n");
printf("银行家算法是一种最有代表性的避免死锁的算法。!\n");
}
void request1() //银行家算法
{
char ch;
//小功能提示
printf("\n是否要用随机请求? 是请按Y/y,否则按任意键。\n");
scanf("%s",&ch);
if((ch=='y')||(ch=='Y')){AI();printf("\n\n");}
else
{
printf("\n请输入请求资源的进程号 ( 从0到%d ) : ",n-1);
scanf("%d",&h);
printf("请输入请求资源向量:\n");
for(i=0;i<m;i++)
{
printf("资源 %d : ",i);
scanf("%d",&request[h][i]);
if(request[h][i]>need[h][i])
{
printf("进程%d申请的资源数大于它所需要的%d类资源数,请重新输入.\n",h,i);
printf("资源 %d : ",i);
scanf("%d",&request[h][i]);
}
else if(request[h][i]>available[i])
{
printf("进程%d申请的资源数大于可利用的%d类资源数,进程%d等待,请重新输入新的进程.\n",h,i,h);
request1();
}
}
}
for(j=0;j<m;j++)
{
available[j]=available[j]-request[h][j];
allocation[h][j]=allocation[h][j]+request[h][j];
need[h][j]=need[h][j]-request[h][j];
}
if(safe()==1) printf("请求分配成功!\n");
else
{
printf("请求分配被拒绝!\n");
available[j]=available[j]+request[h][j];
allocation[h][j]=allocation[h][j]-request[h][j];
need[h][j]=need[h][j]+request[h][j];
}
//想查看现有数据结构的信息吗?(N:不用)
resource();
//恢复
printf("\n是否恢复初始资源分配状态? 是请按Y/y,否则按任意键。\n");
scanf("%s",&ch);
if((ch=='y')||(ch=='Y'))
{
for(i=0;i<m;i++)
available[i]=available1[i];
for(i=0;i<n;i++)
for(j=0;j<m;j++)
need[i][j]=need1[i][j];
for(i=0;i<n;i++)
for(j=0;j<m;j++)
allocation[i][j]=allocation1[i][j];
request1();
}
else
{
request1();
}
}
bool safe() //安全性算法
{
int flag=1,t=0; //计算需要的中间量
int k;
for(i=0;i<n;i++)
finish[i]=0;
for(i=0;i<m;i++)
work[i]=available[i];
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(finish[j]==0)
{
for(k=0;k<m;k++)
{
if(flag==1&&work[k]>=need[j][k])flag=1;
else flag=0;
}
if(flag==1)
{
for(k=0;k<m;k++)
work[k]=work[k]+allocation[j][k];
finish[j]=1;
xulie[t]=j;
t++;
}
flag=1;
}
}
}
for(i=0;i<n;i++)
if(finish[i]==0)break;
if(i<n)
{
printf("系统是不安全的,进程%d等待,请重新输入进程\n",h);
return 0;
}
else if(i==n)
{
printf("系统是安全的。\n安全序列为 :");
for(i=0;i<n-1;i++)
printf("%d --> ",xulie[i]);
printf("%d\n",xulie[n-1]);
return 1;
}
}
void resource()
{ char a;
printf("\n是否查看资源分配状态? 是请按Y/y,否则按任意键。\n");
scanf("%s",&a);
if((a=='y')||(a=='Y'))
{
printf("\n进程数:%d\n",n);
printf("\n资源种类数%d\n:",m);
printf("\n各进程对各资源的总需求数:\n");
for(i=0;i<n;i++)
{
printf("\n进程%d:",i);
for(j=0;j<m;j++)
{printf("需要资源%d共%d个 ",j,max[i][j]);}
printf("!!\n");
}
printf("\n各进程已分配的资源数:\n");
for(i=0;i<n;i++)
{
printf("\n进程%d:\n",i);
for(j=0;j<m;j++)
{printf("已获得资源%d共%d个 ",j,allocation[i][j]);}
printf("!!\n");
}
printf("\n资源的现有数目:\n");
for(i=0;i<m;i++)
printf("资源%d拥有%d个\n",i,available[i]);
}
}
void AI()
{
printf("这是WMF模拟请求!\n");
int j;
h=(int)(10.0*rand()/(RAND_MAX+1.0));//返回0至n之间的随机数值
printf("\n请求资源的进程号为%d: \n",h);
for(i=0;i<m;i++)//m个随机数代替资源
{
j=(int)(10.0*rand()/RAND_MAX+1.0);//返回0至10之间的随机数值
request[h][i]=j;
printf("%d资源%d个\n",h,j);
}
printf("判断开始!:\n");
for(i=0;i<m;i++)
{
if(request[h][i]>need[h][i])
{
printf("因为进程%d申请的资源数大于它所需要的%d类资源数,请重新输入.\n",h,i);
printf("资源 %d : ",i);
scanf("%d",&request[h][i]);
}
else if(request[h][i]>available[i])
{
printf("进程%d申请的资源数大于可利用的%d类资源数,进程%d等待,请重新输入新的进程.\n",h,i,h);
request1();
}
}
}