C语言实现银行家算法和死锁避免

使用c语言实现的银行家检测算法,以及对进程资源的分配模拟

目录

1.数据结构

2.变量说明

3.函数和功能

4.流程图

5.运行效果:

6.源代码


1.数据结构

int Allocation[1000][1000]

分配出去的资源的临接矩阵(行号表示进程编号,列好表示资源编号,值表示分配数量)

int Need[1000][1000]

请求资源的临接矩阵(行号表示进程编号,列号表示资源编号,值表示请求数量)

int Available[1000]

当前剩余的资源数组,索引号表示资源编号

bool Finish[1000]

已完成分配的进程矩阵,索引号表示进程编号

2.变量说明

NP

int

进程数量

NR

int

资源数量

p

int

遍历到的进程编号

r

int

遍历到的资源编号

cnt

int

未配置的进程数量

safe

bool

是否为安全状态

3.函数和功能

loadData()

加载数据(Allocation、Need、Available)

printMsg()

打印当前状态(Allocation、Need、Available)

banker()

使用银行家算法检测状态

run()

进行模拟仿真

4.流程图

banker方法:

 run方法:

 5.运行效果:

当前处于安全状态:

分配资源:

 

 分配的不合理,系统进入不安全状态

 6.源代码

#include<iostream>
#include<cstdio>
#include<vector> 
#include<cstring> 
using namespace std;

int Allocation[1000][1000];
int Need[1000][1000];
int Available[1000];
bool Finish[1000];//是否完成分配 
int NP;//进程数 
int NR;//资源种类数
void loadData(){//加载数据
	NP=5;
	NR=4;
	int allocation[5][4]={{0,0,3,2},{1,0,0,0},{1,3,5,4},{0,3,3,2},{0,0,1,4}};
	int need[5][4]={{0,0,1,2},{1,7,5,0},{2,3,5,6},{0,6,5,2},{0,6,5,6}};
	int available[4]={1,6,2,2};
	for(int p=0;p<NP;p++){
		for(int r=0;r<NR;r++){
			Allocation[p][r]=allocation[p][r];
			Need[p][r]=need[p][r];
		}	
	}
	for(int r=0;r<NR;r++)Available[r]=available[r];
}
void printMsg(){//打印函数 
	printf("--------------------------------\n");
	printf("Allocation:\n");
	printf("\t  R ");
	for(int r=0;r<NR;r++)printf("%-4d",r);
	printf("\n\tP  |");
	for(int r=0;r<NR;r++)printf("----");
	printf("\n");
	for(int p=0;p<NP;p++){
		printf("\t%-3d|",p);
		for(int r=0;r<NR;r++){
			printf("%-4d",Allocation[p][r]);
		}printf("\n");
	}
	printf("Need:\n");
	printf("\t  R ");
	for(int r=0;r<NR;r++)printf("%-4d",r);
	printf("\n\tP  |");
	for(int r=0;r<NR;r++)printf("----");
	printf("\n");
	for(int p=0;p<NP;p++){
		printf("\t%-3d|",p);
		for(int r=0;r<NR;r++){
			printf("%-4d",Need[p][r]);
		}printf("\n");
	}
	printf("Available:\n\t");
	for(int r=0;r<NR;r++)printf("%-3d",Available[r]);
	printf("\n\n");
}
bool banker(){//银行家算法 
	vector<int> safe_seq;
	int cnt;
	/*
		在执行银行家算法检测系统状态时会修改Finish数组和Available数组,
		对后面的操作由影响,所以在算法中使用临时数组进行检测修改 
	*/
	bool finish[1000];//临时数组 
	memcpy(finish,Finish,NP*sizeof(int));
	int available_tmp[1000];//临时数组 
	memcpy(available_tmp,Available,NR*sizeof(int)); 
	//为分配完成的进程计数 
	for(int p=0;p<NP;p++)cnt+=!finish[p];
	//默认处于安全状态 
	bool safe=1;
	
	while(cnt>0&&safe){
		int p;
		//依次遍历所有进程,看是否能分配资源 
		for(p=0;p<NP;p++){
			if(!finish[p]){//该进程未被选中
				int r;
				for(r=0;r<NR;r++){
					if(Need[p][r]>available_tmp[r]){//该进程的请求大于剩余 
						break; 
					}
				}
				if(r==NR){//该进程的请求能满足 
					for(r=0;r<NR;r++){
						available_tmp[r]+=Allocation[p][r];//归还资源 
					}
					safe_seq.push_back(p);
					finish[p]=1;//已选中该进程 
					cnt--;//取出当前进程 
					break;//重新开始下一轮检测 
				}
			}
		}
		if(p==NP){//无法为任何进程分配资源
		 safe=0;
		}
	}
	if(!safe)cout<<"unsafe!!!"<<endl<<endl;
	else{
		cout<<"safe sequence:"; 
		for(int i=0;i<safe_seq.size();i++)cout<<safe_seq[i]<<' ';
		cout<<endl<<endl;
	}
	return safe; 
}
void run(){//模拟仿真 
	int cnt=NP;
	int req[1000];
	while(cnt>0){
		printMsg();
		if(!banker())break;//系统进入不安全状态->退出程序 
		int p;
		printf("输入要分配资源的进程编号:"); 
		scanf("%d",&p);
		if(p==-1)break;//输入-1,退出程序 
		if(!Finish[p]){//该进程为待分配资源的进程 
			bool flag=0;
			printf("资源数量(0-%d):",NR);
			for(int r=0;r<NR;r++){
				scanf("%d",&req[r]);
				if(req[r]>Need[p][r])flag=1;
			}
			if(flag){
				printf("请求不合理!!!\n");
				continue;
			}
			int r;
			for(r=0;r<NR;r++){
				if(req[r]>Available[r]){//该进程的请求大于剩余 
					break; 
				}
			}
			if(r==NR){//该进程的请求能满足
				int finish=0;//是否完成分配 
				for(r=0;r<NR;r++){
					Need[p][r]-=req[r]; 
					if(Need[p][r]==0)finish++;
					Available[r]-=req[r];
					Allocation[p][r]+=req[r];
				}
				if(finish==NR){//已分配所以资源
					Finish[p]=1;//选中该进程 
					for(r=0;r<NR;r++){
						Available[r]+=Allocation[p][r];//归还资源 
						Allocation[p][r]=0;//持有量值零 
					}
					cnt--;//取出当前进程 
				}
			}else{//该请求无法满足 
				printf("无法执行分配!!!\n");
			}
		}else{//进程为已分配完毕的进程 
			printf("已分配完毕!!!\n");
		}
	}
	if(cnt==0){
		printMsg();
		printf("finish!!!\n");
	}
}
int main(){
	loadData();
	//banker();
	run();
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

li345376

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值