银行家算法

银行家算法

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

我们可以把操作系统作为一个银行家。操作系统管理的资金相当于银行家的资源。过程向操作系统请求分配相当于用户资源,银行贷款。
为了保证资金的安全性,银行规定:
(1) 当资金客户最大需求不超过可用资金的银行家可以接受客户;
(2) 贷款,但贷款的总数不能超过最大需求量;
(3) 当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款;
(4) 当顾客得到所需的所有资金后,一定能在有限的时间里归还所有的资金.

银行家算法数据结构

1)可利用资源向量Available   

是个含有m个元素的数组。当中的每个元素代表一类可利用的资源数目。

假设Available[j]=K,则表示系统中现有Rj类资源K个。   

2)最大需求矩阵Max   

这是一个n×m的矩阵。它定义了系统中n个进程中的每个进程对m类资源的最大需求。假设Max[i,j]=K,则表示进程i须要Rj类资源的最大数目为K。   

3)分配矩阵Allocation   

这也是一个n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。假设Allocation[i,j]=K,则表示进程i当前已分得Rj类资源的 数目为K。   

4)需求矩阵Need。

  

这也是一个n×m的矩阵,用以表示每个进程尚需的各类资源数。假设Need[i,j]=K,则表示进程i还须要Rj类资源K个,方能完毕其任务。

  

Need[i,j]=Max[i,j]-Allocation[i,j] 

 

算法 的实现

一、初始化

由用户输入数据,分别对可利用资源向量矩阵AVAILABLE 、 最大需求矩阵MAX 、分配矩阵ALLOCATION、 需求矩阵NEED 赋值。

二、银行家算法

在避免死锁的方法中。所施加的限制条件较弱,有可能获得令人惬意的系统性能。在该方法中把系统的状态分为安全状态和不安全状态。仅仅要能使系统始终都处于安全状态,便能够避免发生死锁。

银行家算法的基本思想是分配资源之前, 推断系统是否是安全的; 若是, 才分配。它是最具有 代表性的避免死锁的算法。

设进程cusneed 提出请求REQUEST [i] ,则银行家算法按例如以下规则进行推断。

(1) 假设REQUEST [cusneed] [i]<= NEED[cusneed][i] ,则转(2) ;否则。出错。

(2) 假设REQUEST [cusneed] [i]<= AVAILABLE[cusneed][i] ,则转(3) ;否则。出错。

(3) 系统试探分配资源。改动相关数据:

         AVAILABLE[i]-=REQUEST[cusneed][i];

         ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];

         NEED[cusneed][i]-=REQUEST[cusneed][i];

(4) 系统运行安全性检查,如安全,则分配成立。否则试探险性分配作废,系统恢复 原状, 进程等待。

三、安全性检查算法

(1) 设置两个工作向量Work=AVAILABLE;FINISH

(2) 从进程集合中找到一个满足下述条件的进 程,

FINISH==false;

NEED<=Work;

如找到,运行(3) ; 否则,运行(4)

(3) 设进程获得资源。可顺利运行。直至完 成,从而释放资源。

Work+=ALLOCATION;

Finish=true;

GOTO 2

(4) 如全部的进程Finish= true ,则表 示安全。否则系统不安全。

操作系统安全状态和不安全状态:   

安全序列是指一个进程序列{P1。…,Pn}是安全的,假设对于每个进程Pi(1≤i≤n),它以后尚须要的资源量不超过系统当前剩余资源量与全部进程Pj (j < i )当前占有资源

量之和。
假设存在一个由系统中全部进程构成的安全序列P1。…,Pn,则系统处于安全状态。安全状态一定是没有死锁发生。
不存在一个安全序列。不安全状态不一定导致死锁。

 

各算法流程图

初始化算法流程图:

银行家算法

银行家算法流程图:

银行家算法安全性算法流程 图:

银行家算法 

#include <iostream>
using namespace std;
#define MAXPROCESS 50                        /*最大进程数*/
#define MAXRESOURCE 100                        /*最大资源数*/
int AVAILABLE[MAXRESOURCE];                    /*可用资源数组*/
int MAX[MAXPROCESS][MAXRESOURCE];            /*最大需求矩阵*/
int ALLOCATION[MAXPROCESS][MAXRESOURCE];    /*分配矩阵*/
int NEED[MAXPROCESS][MAXRESOURCE];            /*需求矩阵*/
int REQUEST[MAXPROCESS][MAXRESOURCE];        /*进程须要资源数*/
bool FINISH[MAXPROCESS];                        /*系统是否有足够的资源分配*/
int p[MAXPROCESS];                             /*记录序列*/
int m,n;                                    /*m个进程,n个资源*/
void Init();
bool Safe();
void Bank();
void showdata(int,int);
int main()
{
	Init();
	Safe();
	Bank();
}
void Init()                /*初始化算法*/
{
	int i,j;
	cout<<"请输入进程的数目:";
	cin>>m;
	cout<<"请输入资源的种类:";
	cin>>n;
	cout<<"请输入每一个进程最多所需的各资源数,依照"<<m<<"x"<<n<<"矩 阵输入"<<endl;
	for(i=0;i<m;i++)
		for(j=0;j<n;j++)
			cin>>MAX[i][j];
	cout<<"请输入每一个进程已分配的各资源数,也依照"<<m<<"x"<<n<<"矩 阵输入"<<endl;
	for(i=0;i<m;i++)
	{
		for(j=0;j<n;j++)
		{
			cin>>ALLOCATION[i][j];
			NEED[i][j]=MAX[i][j]-ALLOCATION[i][j];
			if(NEED[i][j]<0)
			{
				cout<<"您输入的第"<<i+1<<"个进程所拥有的第"<<j+1<<"个资源数 错误,请又一次输入:"<<endl;
				j--;
				continue;
			}
		}
	}
	cout<<"请输入各个资源现有的数目:"<<endl;
	for(i=0;i<n;i++)
	{
		cin>>AVAILABLE[i];
	}
}
void Bank()                /*银行家算法*/
{
	int i,cusneed,flag = 0;
	char again;
	while(1)
	{
		showdata(n,m);////////////////////////////////////////////////////////////////////
		cout<<endl;
input:
		cout<<"请输入要申请资源的进程号(注:第1个进程号为0,依次类推)"<<endl;
		cin>>cusneed;
		if (cusneed > m)
		{
			cout<<"没有该进程。请又一次输入"<<endl;
			goto input;
		}
		cout<<"请输入进程所请求的各资源的数量"<<endl;
		for(i=0;i<n;i++)
		{
			cin>>REQUEST[cusneed][i];
		}
		for(i=0;i<n;i++)
		{
			if(REQUEST[cusneed][i]>NEED[cusneed][i])//假设用户选择的线程的第i个资源请求数>该线程该资源所需的数量
			{
				cout<<"您输入的请求数超过进程的需求量!请又一次输入!"<<endl;
				goto input;
			}
			if(REQUEST[cusneed][i]>AVAILABLE[i])//假设用户选择的线程的第i个资源请求数>系统现有的第i个资源的数量
			{
				cout<<"您输入的请求数超过系统有的资源数!请又一次输入!"<<endl;
				goto input;
			}
		}
		for(i=0;i<n;i++)//假设请求合理,那么以下
		{
			AVAILABLE[i]-=REQUEST[cusneed][i];//系统可用资源减去申请了的
			ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];//线程被分配的资源加上已申请了的
			NEED[cusneed][i]-=REQUEST[cusneed][i];//线程还须要的资源减去已申请得到的
		}
		if(Safe())//AVAILABLE  ALLOCATION  NEED变动之后。是否会导致不安全
		{
			cout<<"允许分配请求!"<<endl;
		}
		else
		{
			cout<<"您的请求被拒绝!"<<endl;
			for(i=0;i<n;i++)
			{
				AVAILABLE[i]+=REQUEST[cusneed][i];
				ALLOCATION[cusneed][i]-=REQUEST[cusneed][i];
				NEED[cusneed][i]+=REQUEST[cusneed][i];
			}
		}
		for (i=0;i<n;i++)
		{
			if (NEED[cusneed][i] <= 0)
			{
				flag++;
			}
		}
		if (flag == n)//假设该进程各资源都已满足条件。则释放资源
		{
			for (i=0;i<n;i++)
			{
				AVAILABLE[i] += ALLOCATION[cusneed][i];
				ALLOCATION[cusneed][i] = 0;
				NEED[cusneed][i] = 0;
			}
			cout<<"线程"<<cusneed<<" 占有的资源被释放!

"<<endl; flag = 0; } for(i=0;i<m;i++)//分配好了以后将进程的标识FINISH改成false { FINISH[i]=false; } cout<<"您还想再次请求分配吗?是请按y/Y,否请按其他键"<<endl; cin>>again; if(again=='y'||again=='Y') { continue; } break; }}bool Safe() /*安全性算法*/{ int i,j,k,l=0; int Work[MAXRESOURCE]; /*工作数组*/ for(i=0;i<n;i++) Work[i]=AVAILABLE[i]; for(i=0;i<m;i++) { FINISH[i]=false;//FINISH记录每一个进程是否安全 } for(i=0;i<m;i++) { for(j=0;j<n;j++)//循环查找第i个进程须要的各个资源数 是否 超过系统现有的相应的资源数 { if(NEED[i][j]>Work[j])//第i个进程须要的第j个资源数 > 系统现有的第j个资源数 { break; } } if(j==n)//假设第i个进程所需的各个资源数都没有超过系统现有的相应资源数 { FINISH[i]=true;//给该进程的FINISH标记为true for(k=0;k<n;k++) { Work[k]+=ALLOCATION[i][k];//将Work赋值为 第i个进程各个已分配资源数+系统现有的相应资源数(由于当改进程所有资源数都满足时线程结束并将资源返还给系统) } p[l++]=i;//记录进程号 } else//假设超过继续循环下一个进程 { continue; } if(l==m)//当全部进程都可以被满足执行时 { cout<<"系统是安全的"<<endl; cout<<"安全序列:"<<endl; for(i=0;i<l;i++)//改了146行的i值,显示资源分配给进程的顺序 { cout<<p[i]; if(i!=l-1) { cout<<"-->"; } } cout<<""<<endl; return true; } }//for循环 cout<<"系统是不安全的"<<endl; return false;}void showdata(int n,int m) //显示{ int i,j; cout<<endl; cout<<"-------------------------------------------------------------"<<endl; cout<<"系统可用的资源数为: "; for (j=0;j<n;j++) cout<<" "<<AVAILABLE[j]; cout<<endl; cout<<"各进程还须要的资源量:"<<endl; for (i=0;i<m;i++) { cout<<" 进程"<<i<<":"; for (j=0;j<n;j++) cout<<" "<<NEED[i][j]; cout<<endl; } cout<<endl; cout<<"各进程已经得到的资源量: "<<endl<<endl; for (i=0;i<m;i++) { cout<<" 进程"<<i<<":"; for (j=0;j<n;j++) cout<<" "<<ALLOCATION[i][j]; cout<<endl; } cout<<endl; }




版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/117816.html原文链接:https://javaforall.net

(0)
上一篇 2021年12月30日 下午9:00
下一篇 2021年12月30日 下午9:00


相关推荐

  • 77道Spring面试题以及参考答案(2021年最新版)

    77道Spring面试题以及参考答案(2021年最新版)一、Spring概述1.什么是spring?Spring是一个轻量级Java开发框架,最早有RodJohnson创建,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/JavaEEfull-stack(一站式)轻量级开源框架,为开发Java应用程序提供全面的基础架构支持。Spring负责基础架构,因此Java开发者可以专注于应用程序的开发。Spring最根本的使命是解决企业级应用开发的复杂性,即简化Java开发。Spring可以做很多事情,它为企

    2022年5月7日
    108
  • n8n汉化背后的国际化工程:从语言包加载机制看开源协作生态

    n8n汉化背后的国际化工程:从语言包加载机制看开源协作生态

    2026年3月15日
    2
  • python,java,c语言哪个好_小萌新

    python,java,c语言哪个好_小萌新大学那会也被这个问题被困惑了大半年,直到毕业拿了几个大厂offer才发现语言的选择也就那一回事,我猜不少人刚入门的人依然被这个问题困扰着,所以决定认真分享一波我的经历。如果你还处于大一,大二,或者刚刚入门阶段,那么我认为,语言的选择并不重要,更重要的是底层/通用基础的学习,例如数据结构,算法,计算机网络这些,因为这些语言,是存在很多相同的特性的,例如你学习了C++,后面要转Java,那么其实还是可以很快就上手的。而且,等到了差不多毕业去应聘校招的时候,其实公司并不会对语言有严格的要求,例如你要面

    2025年8月21日
    5
  • Python读写LMDB文件「建议收藏」

    Python读写LMDB文件「建议收藏」LMDB的全称是LightningMemory-MappedDatabase,它的文件结构简单,包含一个数据文件和一个锁文件。LMDB文件可以同时由多个进程打开,具有极高的数据存取速度,访问简单,不需要运行单独的数据库管理进程,只要在访问数据的代码里引用LMDB库,访问时给文件路径即可。让系统访问大量小文件的开销很大,而LMDB使用内存映射的方式访问文件,使得文件内寻址的开销非常小,使…

    2026年4月18日
    8
  • windows虚拟内存机制

    windows虚拟内存机制

    2022年3月6日
    68
  • TreeView控件绑定到数据源

    TreeView控件绑定到数据源nbsp nbsp nbsp nbsp nbsp nbsp nbsp TreeView 控件绑定到数据源 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp TreeView 控件 nbsp nbsp nbsp nbsp nbsp nbsp nbsp ImageList 控件 nbsp nbsp nbsp nbsp nbsp nbsp nbsp 根节点的文本属性值 nbsp nbsp nbsp nbsp nbsp nbsp nbsp 要绑定的数据表 nbsp nbsp nbsp nbsp nbsp nbsp nbsp 数据表的代码列 nbsp nbsp nbsp nbsp nbsp nbsp nbsp 数据表的名称列 nbsp nbsp nbsp nbsp nbsp nbsp nbsp public

    2026年3月16日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号