银行家算法是避免死锁的一种方式,期间我还以为需要用到系统的api函数,其实总体的思路就是dfs,看最终的情况是否都符合安全性~
MAX[M*N] M个进程对N类资源的最大需求量
AVAILABLE[N] 系统可用资源数
ALLOCATION[M*N] M个进程已经得到N类资源的资源量
NEED[M*N] M个进程还需要N类资源的资源量
2.银行家算法
设进程I提出请求Request[N],则银行家算法按如下规则进行判断。
(1)如果Request[N]<=NEED[I,N],则转(2);否则,出错。
(2)如果Request[N]<=AVAILABLE,则转(3);否则,出错。
(3)系统试探分配资源,修改相关数据:
AVAILABLE=AVAILABLE-REQUEST
ALLOCATION=ALLOCATION+REQUEST
NEED=NEED-REQUEST
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
3.安全性检查
(1)设置两个工作向量WORK=AVAILABLE;FINISH[M]=FALSE
(2)从进程集合中找到一个满足下述条件的进程,
FINISH[i]=FALSE
NEED<=WORK
如找到,执行(3);否则,执行(4)
(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
WORK=WORK+ALLOCATION
FINISH=TRUE
GO TO 2
(4)如所有的进程Finish[M]=true,则表示安全;否则系统不安全。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
开始上课的时候以为银行家算法就是一个dfs,后来看书才明白,银行家算法只是先对一个进程申请临界资源进行预处理,真正的检测是安全性算法,也就是说在安全性检测之前已经分配了资源(擦,如果最后不符合条件,那已经进行预处理了,不就扯了,系统还得把资源从新改回去)~
递归:
void safecheck(state s,int t)
{
if (flag==2)
{
return ;
}
if (t==n)
{
flag=1;
return ;
}
if (t>n)
{
flag=2;
return ;
}
for (int i=0;i<n;i++)
{
int j;
if (!Finish[i])
{
for ( j=0;j<m; j++)
{
if (s.Need[i][j]>Work[j])
break;
}
if (j==m)
{
for (j=0;j<m;j++)
Work[j]=Work[j]+s.Allocation[i][j];
a[k++]=i;
Finish[i]=1;
safecheck(s,t++);
}
safecheck(s,t);
}
}
return ;
}
code:
#include<stdio.h>
#include<iostream>
using namespace std;
#define n 5 //进程数目
#define m 3 //资源数目
int a[n]; //安全序列
struct state
{
int Available[m]; //可以利用的资源
int Max[n][m]; //对资源的最大需求量
int Allocation[n][m]; //已经分配的资源
int Need[n][m]; //进程还需要的资源
}p;
bool safecheck(state s);
void InputAvailable()
{
printf("请输入可利用的资源数:");
for (int i=0;i<m;i++)
scanf("%d",&p.Available[i]);
int i,j;
printf("请输入各类进程所需要的最大资源数{Max}:");
for (i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
scanf("%d",&p.Max[i][j]);
}
}
printf("请输入各个进程已分配的资源数{Allocation}:");
for (i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
scanf("%d",&p.Allocation[i][j]);
p.Need[i][j]=p.Max[i][j]-p.Allocation[i][j];
}
}
}
//银行家算法
void InputRequest(int q,int Request[]) //系统试探着分配资源给请求的进程
{
for (int j=0;j<m;j++)
{
if (Request[j]>p.Need[q][j])
printf("error!");
else if (Request[j]>p.Available[j])
printf("%d类进程需要等待",p);
else
{
p.Available[j]=p.Available[j]-Request[j];
p.Allocation[q][j]=p.Allocation[q][j]+Request[j];
p.Need[q][j]=p.Need[q][j]-Request[j];
}
}
if (safecheck(p))
{
printf("分配成功:");
for (int i=0;i<n;i++)
printf("%d",a[i]);
}
}
//安全性算法
bool safecheck(state s)
{
int Work[m],count=0,k=0,r=0;
bool Finish[n];
int i,j;
for ( j=0;j<m;j++)
Work[j]=s.Available[j];
for ( i=0;i<n;i++)
Finish[i]=false;
while (count<n)
{
for (i=0;i<n;i++)
{
if (Finish[i]==false)
{
for (j=0;j<m;)
{
if (s.Need[i][j]>Work[j])
break;
j++;
}
if (j==m)
{
for (j=0;j<m;j++)
Work[j]=Work[j]+s.Allocation[i][j];
Finish[i]=true;
a[k]=i;
k++;
count=count+1;
}
}
}
r=r+1;
}
if (count==n&&r<=5)
return true;
else
return false;
}
int main()
{
InputAvailable();
int w; //申请资源的进程
int b[m]; //申请资源的进程所许的资源数目
printf("请输入申请资源的进程:");
printf("w=");
scanf("%d",&w);
for (int j=0;j<m;j++)
{
scanf("%d",&b[j]);
}
InputRequest(w,b);
}