银行家算法
银行家算法介绍
众所周知,处理死锁的方法有:预防死锁,避免死锁,检测死锁,解除死锁
银行算法就是采用避免死锁的方法处理死锁的,避免死锁简单来说就是在系统为进程分配资源之前,先计算资源分配的安全性,如果此次分配不会导致系统由安全状态向不安全状态转换,则可以分配资源,反之,则不能分配资源。
银行家算法的数据包括:
资源最大需求量(Max[i])、已分配资源数(Allocation[i])、资源需求量(Need[i])、可用资源(Available[i])、请求资源(Request[i])
银行家算法中导致系统由安全状态向不安全状态转换的因素有:
- Request[i] > Available[i](银行家算法)
- Need[i] > Available[i](安全算法)
所以想要用银行家算法找出满足系统安全状态的安全序列就得从上面这两个因素入手
银行家算法
- 计算Request[i]是否大于Available[i]
- 如果存在 Request[i] > Available[i],直接发生请求错误
- 如果不存在 Request[i] > Available[i],请求成功,先试着分配,数据发生改变,Available[i]-=Request[i] , Need[i]-=Request[i] , Allocation[i]+=Request[i] ,转到安全算法
安全算法
- 判断次数等于进程数,每次都从第一个进程开始判断,每次判断次数等于进程数
- 判断Need[i] < Available[i],如果全部Need[i] < Available[i],满足安全状态,设置一个数组记录进程序号和进程顺序,并且下次判断到此进程时直接跳过,释放已分配资源Allocation[i]:Available[i]+=Allocation[i]
- 如果存在Need[i] > Available[i],不满足安全状态,跳过该进程,执行 2
- 设置一个数组记录安全序列的进程顺序,如果最后得到的安全序列中进程的的个数等于所有进程数,则说明存在一组安全序列可以使此次分配满足安全状态,成功避免死锁
了解了以上原理之后,直接上代码
#include<iostream>
using namespace std;
//定义全局变量
int Max[10][10]={0};//最大需求数
int Allocation[10][10]={0};//已分配资源数
int Need[10][10]={0};//还需请求资源数
int Coursenum=0;//进程数
int Resoursenum=0;//资源数
int Available[10]={0};//可用资源数
int Note[10]={0};//标记已经满足安全序列的进程
int Request[10][10]={0};//进程请求的资源数
int number=0;//记录请求资源的进程序号
int order[10]={0};//用于记录安全序列的进程序号顺序
/*
函数目录
Init() //初始化数据,包括Max,Allocation,Need,Coursenum,Rescoursenum,Available,Note,Request,number
Showinit() //输出初始化列表
bank() //判断Request是否大于Available
safe() //安全算法
updateAvailable(int) //满足安全序列的条件下更新Available
updateAvailable() //更新Request进程的Available
updateNeed(int) //更新满足安全序列的进程的Need
updateNeed() //更新Request进程的Need
updateAllocation(int) //更新满足安全序列的进程的Allocation
updateAllocation() //更新Request进程的Allocation
main()
*/
//输出初始化列表
void Showinit()
{
//输出初始化列表
cout<<"进程"<<" "<<"Max"<<" "<<"Allocation"<<" "<<"Need"<<" "<<"Available"<<endl;
for(int i=0;i<Coursenum;i++)
{
cout<<"P"<<i<<" ";
for(int j=0;j<Resoursenum;j++)
{
cout<<Max[i][j]<<" ";
}
cout<<" ";
for(int j=0;j<Resoursenum;j++)
{
cout<<Allocation[i][j]<<" ";
}
cout<<" ";
for(int j=0;j<Resoursenum;j++)
{
cout<<Need[i][j]<<" ";
}
cout<<" ";
if(i==0)
{
for(int j=0;j<Resoursenum;j++)
{
cout<<Available[j]<<" ";
}
}
cout<<endl;
}
}
//初始化数据
void Init()
{
cout<<"请输入进程数:"<<endl;
cin>>Coursenum;
cout<<"请输入资源数:"<<endl;
cin>>Resoursenum;
//初始化列表
cout<<"请输入最大需求矩阵Max:"<<endl;
for(int i=0;i<Coursenum;i++)
{
for(int j=0;j<Resoursenum;j++)
{
cin>>Max[i][j];
}
}
cout<<"请输入已分配资源矩阵:"<<endl;
for(int i=0;i<Coursenum;i++)
{
for(int j=0;j<Resoursenum;j++)
{
cin>>Allocation[i][j];
}
}
//计算Need
for(int i=0;i<Coursenum;i++)
{
for(int j=0;j<Resoursenum;j++)
{
Need[i][j]=Max[i][j]-Allocation[i][j];
}
}
cout<<"请输入可用资源数:"<<endl;
for(int i=0;i<Resoursenum;i++)
{
cin>>Available[i];
}
//输出请求前的列表
cout<<"请求资源之前的列表为:"<<endl;
Showinit();
//输入请求资源的进程序号
cout<<"请输入请求资源的进程序号(0~Resoursenum):"<<endl;
cin>>number;
//输入Request
cout<<"请输入请求资源数:"<<endl;
for(int i=0;i<Resoursenum;i++)
{
cin>>Request[number][i];
}
}
//银行家算法,先判断Request是否大于Available
int bank()
{
//判断Request是否小于Available
for(int i=0;i<Resoursenum;i++)
{
if(Request[number][i]>Available[i])
{
return 0;//证明Request大于Available
}
}
return 1;//证明Request小于Available
}
//满足安全序列的条件下更新Available
void updateAvailable(int n)
{
for(int i=0;i<Resoursenum;i++)
{
Available[i]+=Allocation[n][i];
}
}
//更新Request进程的Available
void updateAvailable()
{
for(int i=0;i<Resoursenum;i++)
{
Available[i]-=Request[number][i];
}
}
//更新Request进程的Need
void updateNeed()
{
for(int i=0;i<Resoursenum;i++)
{
Need[number][i]-=Request[number][i];
}
}
//更新满足安全序列的进程的Need
void updateNeed(int n)
{
for(int i=0;i<Resoursenum;i++)
{
Need[n][i]=0;
}
}
//更新Request进程的Allocation
void updateAllocation()
{
for(int i=0;i<Resoursenum;i++)
{
Allocation[number][i]+=Request[number][i];
}
}
//更新满足安全序列的进程的Allocation
void updateAllocation(int n)
{
for(int i=0;i<Resoursenum;i++)
{
Allocation[n][i]=0;
}
}
//安全算法
int safe()
{
//判断进程请求是否合理
int flage=bank();
if(flage==0)
{
cout<<"该进程请求不合理!"<<endl;
return 0;
}
else
{
cout<<"该进程请求合理!"<<endl;
cout<<endl;
//试着分配(满足Request)
updateNeed();//更新number进程的Need
updateAvailable();//更新number进程的Available
updateAllocation();//更新number进程的Allocation
//更新完毕之后就要开始找出安全序列
cout<<"更新之后的列表为:"<<endl;
Showinit();//展示更新之后的列表
cout<<endl;
int num=0;//记录满足安全序列的进程个数
for(int i=0;i<Coursenum;i++)
{
for(int j=0;j<Coursenum;j++)//判断Coursenum次,每次都从第一个进程开始判断
{
if(Note[j]==0)//证明没有被记录过
{
cout<<endl;
cout<<"开始判断进程"<<j<<"是否满足安全条件"<<endl;
int flage1=0;//等于0标志满足安全状态,不等于0标志不满足安全状态
for(int k=0;k<Resoursenum;k++)
{
if(Need[j][k]>Available[k])
{
flage1++;
}
}
if(flage1==0)//满足安全序列
{
cout<<"进程P"<<j<<"满足安全条件"<<endl;
order[num]=j;
Note[j]=1;
num++;
updateAvailable(j);//更新Available
updateAllocation(j);//清零Allocation
updateNeed(j);//清零Need
cout<<"分配和回收后的列表为:"<<endl;
Showinit();
}
else
{
cout<<"进程P"<<j<<"不满足安全条件"<<endl;
cout<<endl;
}
}
else
{
break;
}
}
}
cout<<"符合安全序列的进程数为:"<<num<<endl;
if(num==Coursenum)//如果符合安全序列的进程数等于进程数,则说明存在一组安全序列
{
cout<<"存在一组安全序列为:"<<" ";
for(int i=0;i<Coursenum;i++)
{
cout<<"P"<<order[i]<<" ";
}
}
else
{
cout<<"不存在一组安全序列"<<endl;
}
}
return 0;
}
int main()
{
Init();
safe();
}
运行结果如下: