银行家算法

银行家算法是用于解决死锁问题。

相当于动态的模拟一个资源分配的过程,判断哪些可以运行,而后回收资源 重复上两个过程

直到所有进程都能完成。


这里用队列模拟,先将所有进程放进队列,当满足条件出队同时回收资源

当不满足,继续入队

如果在资源未更新的情况下扫到一个进程两次,那么不存在安全序列。


#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;
} 
 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值