操作系统——银行家算法

操作系统——银行家算法自从写完第一篇博客,发现写博客也挺好玩的,比平时写word应付作业有趣的多,而且文章在网上还能帮助别人,自己平时也经常看CSDN,这不,老师要求我们实现一下操作系统的银行家算法,所以我就来了!那么,什么是银行家算法呢?如果你很了解请跳过这一段,就是解决死锁问题的一个算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判…

大家好,又见面了,我是你们的朋友全栈君。

  自从写完第一篇博客,发现写博客也挺好玩的,比平时写word应付作业有趣的多,而且文章在网上还能帮助别人,自己平时也经常看CSDN,这不,老师要求我们实现一下操作系统的银行家算法,所以我就来了!

  那么,什么是银行家算法呢?如果你很了解请跳过这一段,就是解决死锁问题的一个算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行,那么有人又会问什么是死锁?通俗来讲,就是两个进程各占了一个资源,都在等待对方让出资源从而可以进行下一步,下面我找了一张图可以帮助更清楚的认识,T1、T2是两个进程,R1、R2为两个资源。

操作系统——银行家算法

  所以银行家算法产生了,它是借助于银行家借贷时的策略而产生的一种算法,基本思想为两个模块,一个是主模块即银行家算法模块,第二个是安全性检查模块,银行家算法模块要做的是当又进程申请资源时,先检查当前系统是否能够满足进程的需求,如果能满足就试分配,程序进入安全性检查模块,如果不能满足就拒绝申请,从而保证资源不会被“空手套白狼”。

  银行家算法中数据结构主要是几个数组

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]

 

银行家模块:

Request i是进程Pi的请求向量,如果Request i[j]=K,表示进程P i需要KR j类型的资源。当P i发出资源请求后,系统按下述步骤进行检查:

(1) 如果Request i[j]<=Need[i,j],便转向步骤(2);否则认为出错,因为它所需要的资源数已超过它所宣布的最大值。

(2) 如果Request i[j]≤Available[j],便转向步骤(3);否则,表示尚无足够资源,Pi须等待。

(3) 系统试探着把资源分配给进程P i,并修改下面数据结构中的数值:

     Available[j]:= Available[j]-Request i[j];

     Allocation[i,j]:= Allocation[i,j]+Request i[j];

     Need[i,j]:= Need[i,j]-Request i[j];

(4) 系统执行安全性算法,检查此次资源分配后系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。

 

安全性检查模块:

(1) 设置两个向量:

  ① 工作向量Work,它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work:=Available

  ② Finish,它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i]:=false;当有足够资源分配给进程时,再令Finish[i]:=true

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

  ① Finish[i]=false

  ② Need[i,j]≤Work[j];若找到,执行步骤(3),否则,执行步骤(4)

(3) 当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:

    Work[j]:= Work[j]+Allocation[i,j]

    Finish[i]:=true

    go to step 2);

(4) 如果所有进程的Finish[i]=true都满足,则表示系统处于安全状态;否则,系统处于不安全状态。

 

下面来举个栗子:

假定系统有五个进程{P0P1P2P3P4}和三类资源{ABC},各种资源的数量分别为1057,在T0时刻的资源分配情况如图示。 (先忽略P1第二行的括号)

操作系统——银行家算法

(1) T0时刻的安全性:利用安全性算法对T0时刻的资源分配情况进行分析如下图可知,在T0时刻存在着一个安全序列{P1P3P4P2P0},故系统是安全的。

操作系统——银行家算法

(2)  P1请求资源:P1发出请求向量Request1(102),系统按银行家算法进行检查:

  ① Request1(102)≤Need1(122)

  ② Request1(102)≤Available1(332)

  ③ 系统先假定可为P1分配资源,并修改AvailableAllocation1Need1向量,形成的资源变化情况如下图圆括号所示

操作系统——银行家算法

      ④ 再利用安全性算法检查此时系统是否安全。

操作系统——银行家算法

(4)  P0请求资源:P0发出请求向量Requst0(020),系统按银行家算法进行检查:

  ① Request0(020)≤Need0(743)

  ② Request0(020)≤Available(230)

  ③ 系统暂时先假定可为P0分配资源,并修改有关数据

操作系统——银行家算法

(5) 进行安全性检查:可用资源Available(210)已不能满足任何进程的需要,故系统进入不安全状态,此时系统不分配资源。

 

下面则是我的代码实现部分:

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

#define MAX 20

int n_process;//表示进程的个数
int n_resource;//表示资源的个数
int Resource[MAX];//表示资源的总数
int Max[MAX][MAX];//表示进程对每类资源的最大需求量
int Allocation[MAX][MAX];//表示系统给进程已分配每类资源的数目
int Need[MAX][MAX];//表示进程还需各类资源数目
int Available[MAX];//表示系统当前剩下的资源
int Work[MAX];//表示安全性检查的中间变量
bool Finish[MAX];//表示资源是否被安全性检查过
vector<int> Safeorder;//表示安全序列

void Menu()
{
	cout << "------------------Banker----------------------" << endl;
	cout << "*              1.初始化数据                  *" << endl;
	cout << "*              2.申请资源                    *" << endl;
	cout << "*              3.显示资源分配情况            *" << endl;
	cout << "*              4.退出                        *" << endl;
	cout << "----------------------------------------------" << endl;
	cout << "请选择:";
}

void checkInit()
{
	if (n_resource)
	for (int i = 0; i < n_process; i++)
	{
		for (int j = 0; j < n_resource; j++)
		{
			if (Max[i][j] < 0)
				cout << "Max[" << i << "][" << j << "]输入值小于0!" << endl;
			if (Allocation[i][j] < 0)
				cout << "Allocation[" << i << "][" << j << "]输入值小于0!" << endl;
			if (Allocation[i][j]>Max[i][j])
				cout << "Allocation[" << i << "][" << j << "]的值大于Max[" << i << "][" << j << "]输入值" << endl;
		}
	}
	for (int i = 0; i < n_resource; i++)
	{
		if (Available[i]<0)
			cout << "Available[" << i << "]的值小于0!" << endl;
	}
	cout << "输入检查完毕!" << endl;
}


int Init()
{
	if (n_resource != 0 && n_process != 0)
	{
		cout << "你已经初始化过了!" << endl;
		return 1;
	}
	cout << "请分别输入资源个数和进程个数,中间用空格隔开:" << endl;
	cin >> n_resource >> n_process;
	cout << "请输入各个资源的总拥有量:" << endl;
	for (int i = 0; i < n_resource; i++)
		cin >> Resource[i];
	for (int i = 0; i < n_process; i++)
	{
		cout << "P" << i << "对各个资源的最大需求量:" << endl;
		for (int j = 0; j < n_resource; j++)
			cin >> Max[i][j];
		cout << "P" << i << "各个资源已分配量:" << endl;
		for (int j = 0; j < n_resource; j++)
			cin >> Allocation[i][j];
		for (int j = 0; j < n_resource; j++)
			Need[i][j] = Max[i][j] - Allocation[i][j];
	}
	for (int i = 0; i < n_resource; i++)
	{
		int sum[MAX] = { 0 };
		for (int j = 0; j < n_process; j++)
		{
			if (i == 0)
				sum[i] += Allocation[j][i];
			if (i == 1)
				sum[i] += Allocation[j][i];
			if (i == 2)
				sum[i] += Allocation[j][i];
		}
		Available[i] = Resource[i] - sum[i]; 
	}
	checkInit();
	return 1;
}

bool Safecheck()
{
	Safeorder.clear();
	for (int i = 0; i < n_resource; i++)
		Work[i] = Available[i];
	for (int i = 0; i < n_process; i++)
		Finish[i] = false;

	//开始安全性检查
	int count = 0;

	for (int k = 0; k < n_process; k++)
	{
		for (int i = 0; i < n_process; i++)
		{
			if (Finish[i] == false)
			{
				count = 0;
				for (int j = 0; j < n_resource; j++)
				{
					if (Need[i][j] <= Work[j])
						count++;
				}
				if (count == n_resource)
				{
					for (int j = 0; j < n_resource; j++)
					{
						Work[j] = Work[j] + Allocation[i][j];
					}
					Finish[i] = true;
					Safeorder.push_back(i);
				}
			}
		}
	}
	count = 0;
	for (int i = 0; i < n_process; i++)
	{
		if (Finish[i] == true)
			count++;
	}
	if (count == n_process)
		return true;
	else
		return false;
}

int Order()
{
	int n = -1; //请求资源的进程号
	int *Request = new int[n_resource];//表示请求的各个资源数量
	cout << "请输入你要请求的进程号:";
	cin >> n;
	cout << "请输入你要请求各个资源的数量,中间用空格隔开:" << endl;
	for (int i = 0; i< n_resource; i++)
		cin >> Request[i];
	
	//开始判断
	for (int i = 0; i < n_resource; i++)
	{
		if (Need[n][i] < Request[i])
		{
			cout << "好啊你敢骗我,需求量比你的最大需求量还大!玩泥巴去吧!" << endl;
			return 1;
		}
	}
	for (int i = 0; i < n_resource; i++)
	{
		if (Available[i] < Request[i])
		{
			cout << "系统已经满足不了你了,你走吧!" << endl;
			return 1;
		}
	}
	//试分配资源给请求进程,并做安全性检查
	for (int i = 0; i < n_resource; i++)
	{
		Available[i] -= Request[i];
		Allocation[n][i] += Request[i];
		Need[n][i] -= Request[i];
	}
	bool Is_safe=Safecheck();
	if (Is_safe == true)
	{
		cout << "系统已经分配资源给P" << n << "进程了!" << endl;
		cout << "其中一个安全序列为:" << endl;
		for (int i = 0; i < Safeorder.size(); i++)
			cout << "P" << Safeorder.at(i) << "->";
		cout << "End" << endl ;
	}
	else
	{
		cout << "我妈妈说让我不分配资源给你,系统会处于不安全状态!" << endl;
		//恢复试分配之前的现场
		for (int i = 0; i < n_resource; i++)
		{
			Available[i] += Request[i];
			Allocation[n][i] -= Request[i];
			Need[n][i] += Request[i];
		}
	}
	return 1;
}
 
void Display()
{
	cout << endl;
	cout << "进程 \t Max \t Allocation\tNeed\tAvailable" << endl;
	for (int i = 0; i < n_process; i++)
	{
		cout << " P" << i << " \t";
		for (int j = 0; j < n_resource; j++)
		{
			cout << Max[i][j] << " ";
		}
		cout << "\t   ";
		for (int j = 0; j < n_resource; j++)
		{
			cout << Allocation[i][j] << " ";
		}
		cout << "\t";
		for (int j = 0; j < n_resource; j++)
		{
			cout << Need[i][j] << " ";
		}
		cout << "\t  ";
		for (int j = 0; i==0&&j < n_resource; j++)
		{
			cout << Available[j] << " ";
		}
		cout << endl;
	}
	cout << endl;
}

int main()
{
	int choose = 0;
	while (1)
	{
		Menu();
		cin >> choose;
		switch (choose)
		{
		case 1:
			Init();
			break;
		case 2:
			Order();
			break;
		case 3:
			Display();
			break;
		case 4:
			cout << "系统已退出!";
			return 1;
		default:
			cout << "就1-4这你都能输错???" << endl;
			break;
		}
	}
}

 

附上一些程序运行截图

程序菜单界面:

操作系统——银行家算法

初始化数据:

操作系统——银行家算法

P1申请资源:

操作系统——银行家算法

P4申请资源:

操作系统——银行家算法

P0申请资源:

操作系统——银行家算法

 

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux设置和修改时间与时区命令_linux 文件修改时间

    linux设置和修改时间与时区命令_linux 文件修改时间linux系统时间有两个,一个是硬件时间,即BIOS时间,就是我们进行CMOS设置时看到的时间,另一个是系统时间,是linux系统Kernel时间。当Linux启动时,系统Kernel会去读取硬件时钟的设置,然后系统时钟就会独立于硬件运作。有时我们会发现系统时钟和硬件时钟不一致,因此需要执行时间同步。方法一一、date查看/设置系统时间1、将日期设置为2017年11月3日[root@linux

    2025年7月21日
    4
  • SSDP协议_Smb协议

    SSDP协议_Smb协议SSDP就是简单服务发现协议(SimpleServiceDiscoveryProtocol)是一种应用层协议,它是构成通用即插即用(也就是UPnP,UPnP是各种各样的智能设备、无线设备和个人电脑等实现遍布全球的对等网络连接的结构)技术的核心协议之一。    简单服务发现协议提供了在局部网络里面发现设备的机制。控制点(也就是接受服务的客户端)能够直接通过使用简单服务发现协议,根据自己的需要查询…

    2022年10月11日
    3
  • JVM垃圾回收算法与参数配置

    JVM垃圾回收算法与参数配置引用计数法这是个古老而经典的垃圾收集算法 其核心就是在对象被其他所引用时计数器 1 而当引用失效时 1 但是这种方式有非常严重的问题 无法处理循环引用的情况 还有就是每次进行加减操作比较浪费系统性能 标记清除法分为标记和清除两个阶段进行处理内存中的对象 当然这种方式也有非常大的弊端 就是空间碎片问题 垃圾回收后的空间不连续 不连续的内存空间工作效率低于连续的内存空间 复制算法 java

    2025年9月28日
    3
  • ureport2 mysql_springboot整合UReport2「建议收藏」

    ureport2 mysql_springboot整合UReport2「建议收藏」###1、首先新建一个springboot项目###可以用idea直接新建,也可以在spring-boot官方提供的生成器生成项目,生成地址是:[https://start.spring.io/][https_start.spring.io]###2、配置pom.xml###org.springframework.bootspring-boot-starter-jdbcmysqlmysql…

    2025年7月30日
    3
  • shiro的面试题_综合分析面试题

    shiro的面试题_综合分析面试题Shiro框架介绍shiro安全数据源有哪些:Shiro运行流程Shiro的优点比较SpringSecurity和Shiro简述Shiro的3个核心组件 1.Subject 2.SecurityManager 3.RealmsShiro认证过程Shiro授权过程Shiro如何自实现认证如何实现自实现授权如何配置在Spring中配置使用Shiro

    2022年10月14日
    2
  • Hadoop体系_集团架构

    Hadoop体系_集团架构目录2.1Hadoop简介2.1.1Hadoop由来2.1.2Hadoop发展历程2.1.3Hadoop生态系统2.2Hadoop的体系架构2.2.1分布式文件系统HDFS2.2.2分布式计算框架MapReduce2.2.3分布式资源调度系统YARN2.2.4三大发行版本2.1Hadoop简介自从大数据的概念被提出后,出现了很多相关技术,其中对大数据发展最有影响力的就是开源分布式计算平台Hadoop,它就像软件发展史上的Win…

    2022年10月17日
    2

发表回复

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

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