#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
# define m 50
# define true 1
# define false 0
int no1; //进程数
int no2; //资源数
int r;
int allocation[m][m],need[m][m],available[m],max[m][m];
char name1[m],name2[m]; //定义全局变量
void main()
{
void check();
void print(); //提前声明
int i,j,p=0,q=0;
char c;
int request[m],allocation1[m][m],need1[m][m],available1[m];
printf("**********************************************\n");
printf("* 银行家算法的设计与实现 *\n");
printf("**********************************************\n");
printf("请输入进程总数:\n");
scanf("%d",&no1);
printf("请输入资源种类数:\n");
scanf("%d",&no2);
printf("请输入Max矩阵:\n");
for(i=0;i<no1;i++)
for(j=0;j<no2;j++)
scanf("%d",&max[i][j]); //输入已知进程最大资源需求量
printf("请输入Allocation矩阵:\n");
for(i=0;i<no1;i++)
for(j=0;j<no2;j++)
scanf("%d",&allocation[i][j]); //输入已知的进程已分配的资源数
for(i=0;i<no1;i++)
for(j=0;j<no2;j++)
need[i][j]=max[i][j]-allocation[i][j]; //根据输入的两个数组计算出need矩阵的值
printf("请输入Available向量\n");
for(i=0;i<no2;i++)
scanf("%d",&available[i]); //输入已知的可用资源数
print(); //输出已知条件
check(); //检测T0时刻已知条件的安全状态
if(r==1) //如果安全则执行以下代码
{
do{
q=0;
p=0;
printf("\n请输入请求资源的进程号:\n");
for(j=0;j<=10;j++)
{
scanf("%d",&i);
if(i>=no1)
{
printf("输入错误,请重新输入:\n");
continue;
}
else break;
}
printf("\n请输入该进程所请求的资源数request[j]:\n");
for(j=0;j<no2;j++)
scanf("%d",&request[j]);
for(j=0;j<no2;j++)
if(request[j]>need[i][j]) p=1;
//判断请求是否超过该进程所需要的资源数
if(p)
printf("请求资源超过该进程资源需求量,请求失败!\n");
else
{
for(j=0;j<no2;j++)
if(request[j]>available[j]) q=1;
//判断请求是否超过可用资源数
if(q)
printf("没有做够的资源分配,请求失败!\n");
else //请求满足条件
{
for(j=0;j<no2;j++)
{
available1[j]=available[j];
allocation1[i][j]=allocation[i][j];
need1[i][j]=need[i][j];
//保存原已分配的资源数,仍需要的资源数和可用的资源数
available[j]=available[j]-request[j];
allocation[i][j]+=request[j];
need[i][j]=need[i][j]-request[j];
//系统尝试把资源分配给请求的进程
}
print();
check(); //检测分配后的安全性
if(r==0) //如果分配后系统不安全
{
for(j=0;j<no2;j++)
{
available[j]=available1[j];
allocation[i][j]=allocation1[i][j];
need[i][j]=need1[i][j];
//还原已分配的资源数,仍需要的资源数和可用的资源数
}
printf("返回分配前资源数\n");
print();
}
}
}printf("\n你还要继续分配吗?Y or N ?\n");
//判断是否继续进行资源分配
c=getche();
}while(c=='y'||c=='Y');
}
}
void check() //安全算法函数
{
int k,f,v=0,i,j;
int work[m],a[m];
int finish[m];
r=1;
for(i=0;i<no1;i++)
finish[i]=false; // 初始化进程均没得到足够资源数并完成
for(i=0;i<no2;i++)
work[i]=available[i]; //work[i]表示可提供进程继续运行的各类资源数
k=no1;
do{
for(i=0;i<no1;i++)
{
if(finish[i]==false)
{
f=1;
for(j=0;j<no2;j++)
if(need[i][j]>work[j])
f=0;
if(f==1) //找到还没有完成且需求数小于可提供进程继续运行的资源数的进程
{
finish[i]=true;
a[v++]=i; //记录安全序列号
for(j=0;j<no2;j++)
work[j]+=allocation[i][j]; //释放该进程已分配的资源
}
}
}
k--; //每完成一个进程分配,未完成的进程数就减1
}while(k>0);
f=1;
for(i=0;i<no1;i++) //判断是否所有的进程都完成
{
if(finish[i]==false)
{
f=0;
break;
}
}
if(f==0) //若有进程没完成,则为不安全状态
{
printf("系统处在不安全状态!");
r=0;
}
else
{
printf("\n系统当前为安全状态,安全序列为:\n");
for(i=0;i<no1;i++)
printf("p%d ",a[i]); //输出安全序列
}
}
void print() //输出函数
{
int i,j;
printf("\n");
printf("*************此时刻资源分配情况**********************\n");
printf("进程名 | Max | Allocation | Need |\n");
for (i = 0; i < no1; i++)
{
printf(" p%d/%d ",i,i);
for (j = 0; j < no2; j++)
{printf("%d ",max[i][j]);}
for (j = 0; j < no2; j++)
{printf(" %d ",allocation[i][j]);}
for (j = 0; j < no2; j++)
{printf(" %d ",need[i][j]);}
printf("\n");
}
printf("\n");
printf("各类资源可利用的资源数为:");
for (j = 0; j < no2; j++)
{printf(" %d",available[j]);}
printf("\n");
}
1、定义了一个结构体,结构体里面的三个域分别表示三种资源的数量。 2、定义一个最大需求矩阵,写出已分配资源数矩阵、需求矩阵、可用资源 向量、记录安全序列的数组、试探分配序列。 3、银行家算法使用的是试探分配的策略,如果进程请求分配的资源既不大 于自己尚需的资源,又不大于系统现存的资源,那就可以先试探着将资源分配给该进程,然后测试分配后是不是有可能造成死锁,如果不会引起死锁(即安全状态)就可以完成分配,否则(即不安全状态)就将试探分配的资源回收回来让其等待。 | |
① 工作向量Work,它表示系统可提供给进程继续运行所需的各类资源数目, | |
它含有m个元素,在执行安全算法开始时,Work := Available; ② Finish:它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i] := false;当有足够资源分配给进程时,再令Finish[i] := true。实现以下功能。 (2) 从进程集合中找到一个能满足下述条件的进程: 假定系统中有五个进程{P0, P1, P2, P3, P4}和三类资源{A, B, C},各种资源的数量分别为10、5、7,在T0时刻的资源分配情况如图:
|