1、实验目的
(1)通过编写和调试银行家算法的模拟程序以加深对避免死锁方案的理解;
(2)熟悉银行家算法的分配思想。
2、 实验内容及要求
设计一个银行家方案,并编写程序实现。已知系统总共的资源数、进程名、进程已分配的资源、进程运行完毕最大最资源的需求量,以书上例题为例,分析某一时刻系统是否会产生死锁。
假定系统中有五个进程{P0, P1, P2, P3, P4}和三类资源{A, B, C},各种资源的数量分别为10、5、7,在T0时刻的资源分配情况如图所示。
根据银行家算法 :
(1) 判断T0时刻的安全性,如果安全,输出安全序列。
(2) P1请求资源:P1发出请求向量Request1(1,0,2),系统按银行家算法进行检查看是否能进行分配?
3、算法描述
银行家算法中数据结构如下:
n :系统中的进程个数;
m :系统中的资源类数。
1)Available(m):现有资源向量。
Available(j)=k表示k个未分配的j类资源
2)Max(n,m):资源最大申请量矩阵。
Max(i,j)=k表示第i个进程在运行过程中对第j类资源的最大申请量为k。
3)Allocation(n,m):资源分配矩阵。
Allocation(i,j)=k表示进程i已占有k个j类资源。
4)Need(n,m):进程以后还需要的资源矩阵。
Need(i,j)=k表示进程i以后还需要k个第j类资源。
显然有Need[i,j]=Max[i,j]-Allocation[i,j]。
5)Request(n,m):进程申请资源矩阵。
Request(i,j)=k表示进程i申请k个第j类资源。
银行家算法思想如下:
若进程i申请资源,申请资源向量为Request(i),则有如下资源分配过程:
1)如果Request(i)〉Need(i),则报错返回。
2)如果Request(i)〉Avaliable,则进程i进入等待资源状态,返回。
3)假设进程进程i的申请已获批准,于是修改系统状态:
Avaliable=Avaliable-Request(i)
Allocation(i)=Allocation(i)+Request(i)
Need(i)=Need(i)-Request(i)
4)调用安全状态检查算法。
(1)设Work(m)为临时工作向量。初始时Work=Available。令N={1,2,……n}。
(2)寻求j∈N 使其满足:Need(j)<=Work,若不存在这样的j则转至(3)。
Work=Work+Allocation(j) N=N-{j} 转至(2)。
(3)如果N=空集 则返回(系统安全)。如果N≠空集 则返回(系统不安全)。
5)若系统处于安全状态,则将进程i申请的资源分配给进程i,返回。
6)若系统处于不安全状态,则不将进程i申请的资源分配给进程i,恢复原来的资源分配状态,让进程i等待。
Avaliable = Avaliable + Request(i)
Allocation(i)=Allocation(i)-Request(i)
Need(i)=Need(i)+ Request(i)
4、源程序代码
#include
#include
#define False 0
#define True 1
/********主要数据结构********/
char NAME[100]={0};//资源的名称
int Max[100][100]={0};//最大需求矩阵
int Allocation[100][100]={0};//系统已分配矩阵
int Need[100][100]={0};//还需要资源矩阵
int Available[100]={0};//可用资源矩阵
int Request[100]={0};//请求资源向量
int Work[100]={0};//存放系统可提供资源量
int Finish[100]={0}; //标记系统是否有足够的资源分配给各个进程
int Security[100]={0};//存放安全序列
int M=100;//进程的最大数
int N=100;//资源的最大数
/********初始化数据:输入进程数量、资源种类、各进程对资源最大需求量、
各进程的资源已分配数量、各种资源可用数量等。********/
void init()
{
int i,j;
int flag;
//输入系统资源数目及各资源可用个数
printf("系统可用资源种类为:");
scanf("%d",&N);
for(i=0;i头文件
scanf("%c",&NAME[i]);
printf("资源%c的可用个数为:",NAME[i]);
scanf("%d",&Available[i]);
}
//输入进程数及各进程的最大需求矩阵
printf("\n请输入进程的数量:");
scanf("%d",&M);
printf("请输入各进程的最大需求矩阵的值[Max]:\n");
for(i=0;iMax[i][j])
flag=True;
Need[i][j]=Max[i][j]-Allocation[i][j];
}
}
if(flag)
printf("分配的资源大于最大量,请重新输入!\n");
}while(flag);
}
/********显示资源分配矩阵********/
void showdata()
{
int i,j;
printf("\n*************************************************************\n");
printf("\n");
printf("系统当前的资源分配情况如下:\n");
printf(" Max Allocation Need Available\n");
printf("进程名 ");
//输出与进程名同行的资源名,Max、Allocation、Need下分别对应
for(j=0;j<4;j++){
for(i=0;i");
}
printf("\n");
return True;
}
/********利用银行家算法对申请资源进行试分********/
void bank()
{
int flag = True;//标志变量,判断能否进入银行家算法的下一步
int i,j;
printf("请输入请求分配资源的进程号(0-%d):",M-1);
scanf("%d",&i);//输入须申请资源的进程号
printf("请输入进程P%d要申请的资源个数:\n",i);
for(j=0;jNeed[i][j])//判断申请是否大于需求,若大于则出错
{
printf("进程P%d申请的资源大于它需要的资源",i);
printf("分配不合理,不予分配!\n");
flag = False;
break;
}
else
{
if(Request[j]>Available[j])//判断申请是否大于当前可分配资源,若大于则出错
{
printf("进程%d申请的资源大于系统现在可利用的资源",i);
printf("\n");
printf("系统尚无足够资源,不予分配!\n");
flag = False;
break;
}
}
}
//前两个条件成立,试分配资源,寻找安全序列
if(flag)
{
test(i); //根据进程需求量,试分配资源
showdata(); //根据进程需求量,显示试分配后的资源量
if(!safe()) //寻找安全序列
{
printf("分配失败!\n");
Retest(i);
showdata();
}
}
}
int main()//主函数
{
char choice;
init();//初始化数据
showdata();//显示各种资源
//用银行家算法判定系统当前时刻是否安全,不安全就不再继续分配资源
if(!safe()) exit(0);
do{
printf("\n*************************************************************\n");
printf("\n");
printf("\n");
printf("\t-------------------银行家算法演示------------------\n");
printf(" R(r):请求分配 \n");
printf(" E(e):退出 \n");
printf("\t---------------------------------------------------\n");
printf("请选择:");
fflush(stdin); //清空输入流缓冲区的字符,注意必须引入#include头文件
scanf("%c",&choice);
switch(choice)
{
case 'r':
case 'R':
bank();break;
case 'e':
case 'E':
exit(0);
default: printf("请正确选择!\n");break;
}
} while(choice);
}
5、运行结果