银行家算法是由Dijkstra设计的最具有代表性的避免死锁的算法
1.相关概念
(1)安全状态定义:
某时刻,对于并发执行的n个进程,若系统能够按照某种顺序如{p1,p2…pn}
来为每个进程分配所需资源,直至最大需求,从而使每个进程都可顺利完成,则认为该时刻系统处于安全状态,这样的序列为安全序列,安全状态一定是没有死锁发生。
(2)银行家算法(含安全性算法)描述
当Pi发出资源请求后,系统按下述步骤进行检查:
(1) 如果Requesti[j]≤Need[i,j]
,便转向步骤2;否则认为出错,因为它所需要的资源数已超过它所宣布的最大值。
(2) 如果Requesti[j]≤Available[j]
,便转向步骤(3);否则, 表示尚无足够资源,Pi须等待。
(3) 系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值
Available[j]:=Available[j] –Requesti[j];
Allocation[i, j]:=Allocation[i, j]+Requesti[j];
Need[i, j]:=Need[i, j]-Requesti[j];
(4) 系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。
安全性算法描述
(1) 设置两个向量: 在执行安全算法开始时,Work∶=Available; Finish[i]:= False;
(2) 从进程集合中找到一个能满足下述条件的进程: ① Finish[i]= False; ② Need[i,j]≤Work[j];
若找到, 执行步骤(3), 否则,执行步骤(4)。
(3) 当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
Work[j]∶= Work[i]+ Allocation[i, j];
Finish[i]∶= true; go to step 2;
(4) 如果所有进程的Finish[i]=true
都满足, 则表示系统处于安全状态;否则,系统处于不安全状态。
C/C++程序代码及注释
/*子函数声明*/
int Isprocessallover(); //判断系统中的进程是否全部运行完毕
void Systemstatus(); //显示当前系统中的资源及进程情况
int Banker(int ,int *); //银行家算法
void Allow(int ,int *); //若进程申请不导致死锁,用此函数分配资源
void Forbidenseason(int ); //若发生死锁,则显示原因
/*全局变量*/
int Availiable[3]={3,3,2}; //初始状态,系统可用资源量
int Max[5][3]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
//各进程对各资源的最大需求量
int Allocation[5][3]={{0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2}};
//初始状态,各进程占有资源量
int Need[5][3]={{7,4,3},{1,2,2},{6,0,0},{0,1,1},{4,3,1}};
//初始状态时,各进程运行完毕,还需要的资源量
int over[5]={0,0,0,0,0}; //标记对应进程是否得到所有资源并运行完毕
#include <iostream>
using namespace std;
/*主函数*/
int main()
{
int process=0; //发出请求的进程
int decide=0; //银行家算法的返回值
int Request[3]={0,0,0}; //申请的资源量数组
int sourcenum=0; //申请的各资源量
/*判断系统中进程是否全部运行完毕*/
step1: if(Isprocessallover()==1)
{
cout<<"系统中全部进程运行完毕!";
return 0;
}
/*显示系统当前状态*/
Systemstatus();
/*人机交互界面*/
step2: cout<<"\n输入发出请求的进程(输入0退出系统): ";
cin>>process;
if(process==0)
{
cout<<"放弃申请,退出系统!";
return 0;
}
if(process<1||process>5||over[process-1]==1)
{
cout<<"系统无此进程!\n";
goto step2;
}
cout<<"此进程申请各资源(A,B,C)数目:\n";
for(int h=0;h<3;h++)
{
cout<<char(65+h)<<"资源:";
cin>>sourcenum;
Request[h]=sourcenum;
}
/*用银行家算法判断是否能够进行分配*/
decide=Banker(process,Request);
if (decide==0)
{
/*将此进程申请资源分配给它*/
Allow(process,Request);
goto step1;
}
else
{
/*不能分配,显示原因*/
Forbidenseason(decide);
goto step2;
}
}
/*子函数Isprocessallover( )的实现*/
int Isprocessallover()
{
int processnum=0;
for(int i=0;i<5;i++)
{
/*判断每个进程是否运行完毕*/
if(over[i]==1)
processnum++;
}
if(processnum==5)
/*系统中全部进程运行完毕*/
return 1;
else
return 0;
}
/*子函数Systemstatus( )的实现*/
void Systemstatus()
{
cout<<"此刻系统中存在的进程:\n";
for(int i=0;i<5;i++)
{
if(over[i]!=1)
cout<<"P"<<i+1<<" ";
}
cout<<endl;
cout<<"此刻系统可利用资源(单位:个):\n";
cout<<"A B C\n";
for(int a=0;a<3;a++)
{
cout<<Availiable[a]<<" ";
}
cout<<endl;
cout<<"此刻各进程已占有资源如下(单位:个): \n"
<<" A B C\n";
for(int b=0;b<5;b++)
{
if(over[b]==1)
continue;
cout<<"P"<<b+1<<" ";
for(int c=0;c<3;c++)
cout<<Allocation[b][c]<<" ";
cout<<endl;
}
cout<<"各进程运行完毕还需各资源如下(单位:个):\n"
<<" A B C\n";
for(int f=0;f<5;f++)
{
if(over[f]==1)
continue;
cout<<"P"<<f+1<<" ";
for(int g=0;g<3;g++)
cout<<Need[f][g]<<" ";
cout<<endl;
}
}
/*子函数Banker(int ,int &)的实现*/
int Banker(int p,int *R)
{
int num=0; //标记各资源是否能满足各进程需要
int Finish[5]={0,0,0,0,0}; //标记各进程是否安全运行完毕
int work[5]={0,0,0,0,0}; //用于安全检查
int AvailiableTest[3]; //用于试分配
int AllocationTest[5][3]; //同上
int NeedTest[5][3]; //同上
/*判断申请的资源是否大于系统可提供的资源总量*/
for(int j=0;j<3;j++)
{
if(*(R+j)>Availiable[j])
/*返回拒绝分配原因*/
return 1;
}
/*判断该进程申请资源量是否大于初始时其申明的需求量*/
for(int i=0;i<3;i++)
{
if(*(R+i)>Need[p-1][i])
/*返回拒绝原因*/
return 2;
}
/*为检查分配的各数据结构赋初值*/
for(int t=0;t<3;t++)
{
AvailiableTest[t]=Availiable[t];
}
for(int u=0;u<5;u++)
{
for(int v=0;v<3;v++)
{
AllocationTest[u][v]=Allocation[u][v];
}
}
for(int w=0;w<5;w++)
{
for(int x=0;x<3;x++)
{
NeedTest[w][x]=Need[w][x];
}
}
/*进行试分配*/
for(int k=0;k<3;k++) //修改NeedTest[]
{
AvailiableTest[k]-=*(R+k);
AllocationTest[p-1][k]+=*(R+k);
NeedTest[p-1][k]-=*(R+k);
}
/*检测进程申请得到满足后,系统是否处于安全状态*/
for(int l=0;l<3;l++)
{
work[l]=AvailiableTest[l];
}
for(int m=1;m<=5;m++)
{
for(int n=0;n<5;n++)
{
num=0;
/*寻找用此刻系统中没有运行完的进程*/
if(Finish[n]==0&&over[n]!=1)
{
for(int p=0;p<3;p++)
{
if(NeedTest[n][p]<=work[p])
num++;
}
if(num==3)
{
for(int q=0;q<3;q++)
{
work[q]=work[q]+AllocationTest[n][q];
}
Finish[n]=1;
}
}
}
}
for(int r=0;r<5;r++)
{
if(Finish[r]==0&&over[r]!=1)
/*返回拒绝分配原因*/
return 3;
}
return 0;
}
/*子函数Allow(int ,int &)的实现*/
void Allow(int p,int *R)
{
cout<<"可以满足申请!";
static int overnum;
/*对进程所需的资源进行分配*/
for(int t=0;t<3;t++)
{
Availiable[t]=Availiable[t]-*(R+t);
Allocation[p-1][t]=Allocation[p-1][t]+*(R+t);
Need[p-1][t]=Need[p-1][t]-*(R+t);
}
/*分配后判断其是否运行完毕*/
overnum=0;
for(int v=0;v<3;v++)
{
if(Need[p-1][v]==0)
overnum++;
}
if(overnum==3)
{
/*此进程运行完毕,释放其占有的全部资源*/
for(int q=0;q<3;q++)
Availiable[q]=Availiable[q]+Allocation[p-1][q];
/*标记该进程运行完毕*/
over[p-1]=1;
cout<<"进程P"<<p<<"所需资源全部满足,此进程运行完毕!\n";
}
}
/*子函数Forbidenseason(int )的实现*/
void Forbidenseason(int d)
{
cout<<"不能满足申请,此进程挂起,原因为:\n";
switch (d)
{
case 1:cout<<"申请的资源量大于系统可提供的资源量!";break;
case 2:cout<<"申请的资源中有某种资源大于其声明的需求量!";break;
case 3:cout<<"若满足申请,系统将进入不安全状态,可能导致死锁!";
}
}