银行家算法是用于解决死锁问题。
相当于动态的模拟一个资源分配的过程,判断哪些可以运行,而后回收资源 重复上两个过程
直到所有进程都能完成。
这里用队列模拟,先将所有进程放进队列,当满足条件出队同时回收资源
当不满足,继续入队
如果在资源未更新的情况下扫到一个进程两次,那么不存在安全序列。
#include<bits/stdc++.h>
#define Del(a,b) memset(a,b,sizeof(a))
#define Maxn 110 //方便更新进程最大量
#define Maxm 110 //方便更新资源种类最大量
using namespace std;
int n=8,m; //进程数量8和资源种类 3-8
int Available[Maxm]; //每种资源的未分配量
int Maxneed[Maxn][Maxm]; //进程 i对于资源j的总需求量
int nowhav[Maxn][Maxm]; //进程 i已经拥有的资源j的数量
int need[Maxn][Maxm]; //进程 i还需要资源j的数量
int que[Maxn<<4]; //队列用于模拟分配过程
int ans[Maxn]; //用于记录安全序列
int quefront,queend; //que的队列限制
int ansfront,ansend; //ans的队列限制
void init() //初始化
{
Del(Available,0);
Del(Maxneed,0);
Del(nowhav,0);
Del(need,0);
}
void print_Distribution() //输出初始数据
{
printf("可分配资源量:\n");
printf("\t资源:");
for(int i=0;i<m;i++)
printf("%8d",i);
printf("\n");
for(int i=0;i<m;i++)
if(i==0)
printf("\t%13d",Available[i]);
else
printf("%8d",Available[i]);
printf("\n");
printf("总需求量:\n");
for(int i=0;i<n;i++)
{
printf("\t进程%d",i);
for(int j=0;j<m;j++)
{
printf("%8d",Maxneed[i][j]);
}
printf("\n");
}
printf("已分配资源量:\n");
for(int i=0;i<n;i++)
{
printf("\t进程%d",i);
for(int j=0;j<m;j++)
{
printf("%8d",nowhav[i][j]);
}
printf("\n");
}
printf("还需资源:\n");
for(int i=0;i<n;i++)
{
printf("\t进程%d",i);
for(int j=0;j<m;j++)
{
printf("%8d",need[i][j]);
}
printf("\n");
}
}
void Distribution() //随机生成数据
{
srand(time(0)); //生成随机种子
m=3+rand()%6; //资源种类保证3-8
for(int i=0;i<m;i++)
Available[i]=rand()%100; //未分配的在100内
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
Maxneed[i][j]=rand()%100; //总需求量设置在小于100能提高实验成功率
nowhav[i][j]=rand()%(Maxneed[i][j]+1); //保证当前拥有的小于等于最大需求
need[i][j]=Maxneed[i][j]-nowhav[i][j]; //需求量等于这两项之差
}
}
print_Distribution();
}
void initbanker() //初始化银行家所需元素
{
ansfront=ansend=quefront=queend=0; //初始化队列
for(int i=0;i<n;i++)
{
que[queend++]=i; //一开始让所有进程入队列
}
}
bool banker() //银行家算法
{
initbanker();
int flag[10]; //标志是否在资源未变动的情况下遍历两次i进程
Del(flag,0); //初始化
while(quefront<queend) //que不为空
{
int p=que[quefront++]; //接下来是基础的队列操作不再描述
int ff=0;//标志当前进程是否每个资源都得到满足
if(flag[p])
return false;
for(int i=0;i<m;i++)
{
if(need[p][i]<=Available[i]) //可分配时ff++
ff++;
}
if(ff==m) //当满足条件的资源等于总资源记录答案同时更新flag
{
Del(flag,0);
ans[ansend++]=p;
for(int i=0;i<m;i++)
Available[i]+=nowhav[p][i];
}
else
{
flag[p]=1;
que[queend++]=p;
}
}
return true;
}
int main()
{
init();
Distribution();
if(banker())
{
printf("拥有安全序列\n");
while(ansfront<ansend)
{
printf("%d%c",ans[ansfront++],ansfront==ansend?'\n':' ');
}
}
else
printf("不存在安全序列\n");
return 0;
}