银行家算法

概念

银行家算法是荷兰学者Dijkstra为银行系统设计的,以确保银行在发放现金贷款时,不会发生不能满足所有客户需要的情况。后来该算法被用在操作系统中,用于避免死锁

核心思想:在进程提出资源申请时,先预判此分配是否会导致系统进入不安全状态。如果会进入不安全状态,就暂时不答应这次请求,让该进程先阻塞等待。

算法实现(C语言)

数据结构

长度为 m 的一维数组 Available 表示还有多少可用资源
n × m 矩阵 Max 表示各进程对资源的最大需求数
n × m 矩阵 Allocation 表示已经给各进程分配了多少资源
Max - Allocation = Need 矩阵表示各进程最多还需要多少资源
用长度为m的一维数组 Ruquest 表示此进程此次申请的各种资源数

银行家算法步骤

1、检查此次申请是否超过了之前声明的最大需求数
2、检查此时系统剩余的可用资源是否还能满足这次请求
3、试探着分配,更改数据结构
4、用安全性算法检查此次分配是否会导致系统进入不安全状态

安全性算法步骤

检查当前的剩余可用资源是否能满足某个进程的最大需求,如果可以,就把该进程加入安全序列,并把该进程持有的资源全部回收。

不断重复上述过程,看最终是否能让所有的进程都进入安全序列。

要注意的是:系统处于不安全状态未必死锁(由于进程中途可能会释放资源),但死锁时一定处于不安全状态。系统处于不安全状态一定死锁。

代码段

根据上述思想,编写了五个函数:

1、初始化函数 init():输入进程数量、资源种类数量、资源可利用量、进程资源已分配量、进程最大需求量
2、显示当前状态 show_info():显示当前资源分配详细情况
3、安全性算法 is_Safe():用于判断当前状态安全
4、银行家算法bank():进行银行家算法模拟实现的模块
5、主程序main():逐个调用初始化、显示状态银行家算法函数,实现交互功能

#include<bits/stdc++.h>
using namespace std;

int Max[100][100]={0};            //各进程对资源的最大需求数
int Allocation[100][100]={0};     //已经给各进程分配了多少资源
int Need[100][100]={0};           //各进程还需要多少资源
int Available[100]={0};           //总的可用资源
int Request[100]={0};             //进程此次申请的各种资源数
int Afford[100]={0};              //还有多少可用资源,同Avaliable
int Security[100]={0};            //安全序列的进程
char Name[100]={0};               //各类资源名称
int M,N;                          //进程数和资源种类

void init(){
    cout << "请输入可分配的资源种类数量:";
    cin >> N;
    cout << endl;
    for(int i=0;i<N;i++){
        cout << "请输入第" << i+1 << "个资源的名称:";
        cin >> Name[i];
        cout << "请输入" << Name[i] << "资源的可分配数量:";
        cin >> Available[i];
        cout << endl;
    }
    cout << endl << "请输入进程数量:";
    cin >> M;
    cout << endl << "请输入进程的Max矩阵" << endl;
    for(int i=0;i<M;i++){
        for(int j=0;j<N;j++){
            cin >> Max[i][j];      //输入每个进程所需要的各种资源的最大数量
        }
    }
    cout << endl << "请输入进程的Allocation矩阵" << endl;
	int every[100]={0};
	for(int i=0;i<M;i++){
		for(int j=0;j<N;j++){ 
			cin >> Allocation[i][j];     //每个进程已经分配的各种资源的数量
			Need[i][j]=Max[i][j]-Allocation[i][j];  //Need数组通过最大-已经获得
			every[j]+=Allocation[i][j];   //统计每一种类已经分配的资源数量
		}
	}
    for(int j=0;j<N;j++){
		Available[j]=Available[j]-every[j];  //总的-已经分配处去的=现在剩余的可分配数量
	} 
}

void show_info(){
    cout << endl << endl;
	cout << "              " << "****************" << endl;
	cout << "       " <<"系统当前可用的资源矩阵Available:" << endl;
    cout << "              " << "****************" << endl;
    cout << "               ";
	int i;
	for(i=0;i<N;i++)
		cout << "   " << Name[i];
	cout << endl << "               ";
	for(i=0;i<N;i++)
		cout << "   " << Available[i];
	cout << endl << endl;

    cout << "              " << "****************" << endl;
	cout << "         " << "系统当前资源分配情况如下:" << endl;
    cout << "              " << "****************" << endl << endl;
	cout << "    " << "       Max      Allocation     Need      " << endl;
	cout << "进程名  ";

	for(int i=0;i<3;i++){           //资源名称需要打印三次,分别对应max、allocation、need数组
		for(int j=0;j<N;j++){       //打印所有的资源名称 
			cout << Name[j] << "   ";
		}
	} 
	cout << endl;
	for(int i=0;i<M;i++){           //打印进程每个进程的三种矩阵
	    cout << " Pro" << i;
	 	for(int j=0;j<N;j++){
	 		cout << "   " << Max[i][j];
		}
		for(int j=0;j<N;j++){
	 		cout << "   " <<Allocation[i][j];
		}
		for(int j=0;j<N;j++){
	 		cout << "   " << Need[i][j];
		}
		cout << endl;
	}	
}

bool is_Safe(){
	int isAfford[100]={0};        //是否有足够的资源分配给进程,使之完成运行(够为1,不够为0)
	for(int i=0;i<N;i++){
		Afford[i]=Available[i];   //在执行安全算法开始时,Work=Available 
	}
	int count=0,m=0;              //count是用来统计系统足够某个进程所需要的某种资源数量
	for(int i=0;i<M;i++){	
		count=0;
		for(int j=0;j<N;j++){
			if(isAfford[i]==0 && Need[i][j]<=Afford[j]){   //如果进程没有执行且资源需求条件满足 
				count++;              //这种资源是够的
				if(count==N){         //表示对于i号进程所有资源都满足
					isAfford[i]=1;    //记录i号进程为可执行 
					for(int k=0;k<N;k++){
						Afford[k]=Afford[k]+Allocation[i][k];   //进程执行成功,回收各资源
					}
					Security[m++]=i;  //此进程可以进入安全序列
					i=-1;             //将i置为-1;通过for循环执行i++后变为0,从第一个进程重新开始找 
				} 
			} 
		}
	}
	for(int i=0;i<M;i++){             //依次检查各进程,如果有一个不满足,就说明不安全
		if(isAfford[i]==0){
			cout << endl << "系统不安全" << endl;
			return false;
		}
	} 
	cout << endl << "系统安全" << endl << endl;
	cout << "一个安全序列为:";
	for(int i=0;i<M;i++){
	 	cout << "P" << Security[i];
	 	if(i<M-1)
	 		cout << "-->";
	}
	cout << endl << endl;
	return true;
}

bool bank(){
	cout << "请输入手动分配资源的进程编号:";   
	int id;
	bool flag=true;
	while(cin >> id){
		if(id < 0 || id > M-1){
			cout << endl << "进程不存在!请重新输入!" << endl;
            cout << endl << "请重新输入希望手动分配资源的进程的编号:";
        }
		else break;
	}
	cout << endl << "请分别输入各类请求资源数(" << N << "个):";
	for(int i=0;i<N;i++){
		cin >> Request[i];
	}
	cout << endl << "开始为进程Pro" << id << "分配资源,请等待..." << endl;
	for(int i=0;i<N;i++){
		if(Request[i]>Need[id][i]){
			cout << "进程请求资源数大于所需资源数,无法分配!" << endl;
			flag=false;
			break;			
		}
		else if(Request[i]>Available[i]){
			cout << "进程请求资源数大于可用资源数,无法分配!" << endl;
			flag=false;
			break;
		}
		else{
			Available[i] -= Request[i];           //可用资源数减少
	        Allocation[id][i] += Request[i];      //已分配资源数增加
	        Need[id][i] -= Request[i];            //所需资源数减少
		}
	}
	if(flag==true){
		if(is_Safe())
	       	cout << "分配资源完成!" << endl;
		else{
			for(int i=0;i<N;i++){
				Available[i] += Request[i];           //分配资源回收 
	        	Allocation[id][i] -= Request[i];      
	        	Need[id][i] += Request[i];           
			}
			cout << endl <<"此次分配会导致系统不安全,无法分配!" << endl; 
		}
	}
	return flag; 
}

int main(){

    cout << "              " << "****************" << endl;
	cout << "                 " << "银行家算法" << endl;
    cout << "              " << "****************" << endl << endl;
	init();	
	show_info();
	is_Safe();

	cout << "              " << "****************" << endl;
    cout << "               " << "手动进行资源请求" << endl;
    cout << "               " << "输入R/r请求资源" << endl;
    cout << "               " << "输入E/e退出程序" << endl;
    cout << "              " << "****************" << endl;
    
    char choice;
	while(true){
		cout << endl << "请选择资源分配(R/r)还是退出(E/e):";	
		cin >> choice; 
		cout << endl;
		if(choice=='R'||choice=='r'){
			if(bank()){          //可分配 
				show_info();     //展示信息 
			}           //这边由于上述bank()算法已经进行了安全性检查,此处无需再次调用
            else{ 
				show_info();
			}				
		}
		else if(choice=='E'||choice=='e'){
            cout << "退出程序成功!" << endl;
			exit(0);
		}
		else
			printf("请正确选择!"); 
	}
	return 0;	
} 

运行结果

初始化
在这里插入图片描述
输出当前系统的可用资源数,每个进程的最大需求数、已分配资源数和仍需资源数,并检测系统是否安全,并返回一个安全序列
在这里插入图片描述
银行家算法分配资源,如果资源可分配,更改数据结构并显示分配成功
在这里插入图片描述
如果请求的分配导致系统不安全,则拒绝这次请求
在这里插入图片描述
请求的资源不合理也会拒绝分配
在这里插入图片描述

  • 25
    点赞
  • 111
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值