实验六 银行家算法的模拟与实现

2024-03-27 08:38

本文主要是介绍实验六 银行家算法的模拟与实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、实验目的

(1) 进一步了解进程的并发执行。
(2) 加强对进程死锁的理解,理解安全状态与不安全状态的概念。
(3) 掌握使用银行家算法避免死锁问题。

2、实验基本知识及原理

(1)基本概念
死锁:多个进程在执行过程中,因为竞争资源会造成相互等待的局面。如果没有外力作用,这
些进程将永远无法向前推进。此时称系统处于死锁状态或者系统产生了死锁。
安全序列:系统按某种顺序并发进程,并使它们都能达到获得最大资源而顺序完成的序列为安
全序列。
安全状态:能找到安全序列的状态称为安全状态,安全状态不会导致死锁。
不安全状态:在当前状态下不存在安全序列,则系统处于不安全状态。
(2)银行家算法
银行家算法顾名思义是来源于银行的借贷业务,一定数量的本金要满足多个客户的借贷周转,
为了防止银行家资金无法周转而倒闭,对每一笔贷款,必须考察其是否能限期归还。
在操作系统中研究资源分配策略时也有类似问题,系统中有限的资源要供多个进程使用,必须
保证得到的资源的进程能在有限的时间内归还资源,以供其它进程使用资源。如果资源分配不当,
就会发生进程循环等待资源,则进程都无法继续执行下去的死锁现象。
当一进程提出资源申请时,银行家算法执行下列步骤以决定是否向其分配资源:
1)检查该进程所需要的资源是否已超过它所宣布的最大值。
2)检查系统当前是否有足够资源满足该进程的请求。
3)系统试探着将资源分配给该进程,得到一个新状态。
4)执行安全性算法,若该新状态是安全的,则分配完成;若新状态是不安全的,则恢复原状
态,阻塞该进程。

3、实验内容

本实验的内容是要通过编写和调试一个模拟系统动态分配资源的银行家算法程序,有效地避免
死锁发生。具体要求如下:
(1) 初始化时让系统拥有一定的资源;
(2) 用键盘输入的方式允许进程动态申请资源;
(3) 如果试探分配后系统处于安全状态,则修改系统的资源分配情况,正式分配资源;
(4) 如果试探分配后系统处于不安全状态,则提示不能满足请求,恢复原状态并阻塞该进程

代码实现:

/*
2021-12-17
操作系统课程设计
@浩茫*/
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int n;//进程数
int m; //资源数量int Claim[10][10]; //最大需求矩阵
int Resource[10]; //资源总量
int Allocation[10][10]; //分配矩阵
int Need[10][10];   //需求矩阵
int Available[10]; //可用资源向量
int Request[10];   //请求向量当前进程对各类资源的申请量
int secuer_path[10];void Input()
{int i,j;cout<<"资源总量Available:\n";for(i=0; i<m; i++){cin>>Resource[i];}cout<<"最大需求矩阵Claim:\n";for(i=0; i<n; i++){for(j=0; j<m; j++){cin>>Claim[i][j];}}cout<<"分配矩阵Allocation:\n";for(i=0; i<n; i++){for(j=0; j<m; j++){cin>>Allocation[i][j];}}//需求矩阵=C-Afor(i=0; i<n; i++){for(j=0; j<m; j++){Need[i][j]=Claim[i][j]-Allocation[i][j];}}//初始化:当前可用资源数=总资源数for(i=0; i<m; i++){Available[i]=Resource[i];}//当前可用资源数= 总资源数-已分配资源数for(i=0; i<n; i++){for(j=0; j<m; j++){Available[j]=Available[j]-Allocation[i][j];}}}//比较进程为a中的元素全大于b中的元素返回1,否则返回0
int compare(int a[],int b[])
{int i;for(i=0; i<m; i++){if(a[i]<b[i]){return 0;}}return 1;
}bool test()
{int i,j,k,l;int  program_finished=0;//可以完成运行的进程数量bool flag=0;bool finish[n];int work[m];int x=0;for(i=0; i<n; i++){finish[i]=0;//初始状态都没完成运行}for(i=0; i<m; i++){work[i]=Available[i];}while(program_finished!=n){//进行一轮检查bool flag=false;//for(i=0; i<n; i++) //每一轮至少要加入一个进程,否则就是不安全状态{if(finish[i]==true){continue;}else{if(compare(work,Need[i]))//Available>=Need{finish[i]=true;program_finished++;flag=true;//更新每种资源数量for (j = 0; j <m; j++){work[j] = work[j] +Allocation[i][j];}}elsecontinue;}}if(flag==false){return false;}}for(i=0; i<n; i++){if(finish[i]==0){return false;//不存在安全序列}}return true;//存在安全序列
}
//申请进程后的安全性检验函数
int  secuer_test(int num)
{int i,j;//n=n-1;if(compare(Available,Request)&&compare(Need[num-1],Request))//Available>=Request 并且 Need >=Request{for(j=0; j<m; j++){Allocation[num-1][j]=Allocation[num-1][j]+Request[j];Need[num-1][j]=Need[num-1][j]-Request[j];Available[j]=Available[j]-Request[j];}if(test()){return 1;}else{//撤销资源分配for(j=0; j<m; j++){Allocation[num-1][j]=Allocation[num-1][j]-Request[j];Need[num-1][j]=Need[num-1][j]+Request[j];Available[j]=Available[j]+Request[j];}return 0;}}else{return -1;}}
void show_current()
{int i =0;int j=0;cout<<"         claim      Allocation    Need ";for(i=0; i<n; i++){cout<<"\n进程"<<i+1<<"    ";for(j=0; j<m; j++){cout<<" "<<Claim[i][j];}cout<<"     ";for(j=0; j<m; j++){cout<<" "<<Allocation[i][j];}cout<<"       ";for(j=0; j<m; j++){cout<<" "<<Need[i][j];}cout<<"     ";}cout<<"\n当前剩余资源数量:";for(i=0; i<m; i++){cout<<" "<<Available[i];}cout<<endl;}
int main()
{int i,p;int num;cout<<"进程数:";cin>>n;cout<<"资源种类数:";cin>>m;Input();//初始化if(test()){cout<<"\n存在安全序列,初始状态安全\n\n";show_current();cout<<"\n\n";}else{cout<<"不存在安全序列,初始状态不安全\n";return 0;}while(true){cout<<"输入发出请求Request的进程编号:";cin>>num;cout<<"输入请求的资源数:";for(i=0; i<m; i++){cin>>Request[i];}switch(secuer_test(num)){case 1:cout<<"系统处于安全状态,资源分配成功\n";show_current();break;case 0:cout<<"系统进入不安全状态,资源分配失败,进程阻塞\n";return 0 ;case -1:cout<<"申请资源量不合法,重新输入\n";}}return 0;
}

这篇关于实验六 银行家算法的模拟与实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/851539

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

深入理解Mysql OnlineDDL的算法

《深入理解MysqlOnlineDDL的算法》本文主要介绍了讲解MysqlOnlineDDL的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小... 目录一、Online DDL 是什么?二、Online DDL 的三种主要算法2.1COPY(复制法)

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

Linux挂载linux/Windows共享目录实现方式

《Linux挂载linux/Windows共享目录实现方式》:本文主要介绍Linux挂载linux/Windows共享目录实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录文件共享协议linux环境作为服务端(NFS)在服务器端安装 NFS创建要共享的目录修改 NFS 配

通过React实现页面的无限滚动效果

《通过React实现页面的无限滚动效果》今天我们来聊聊无限滚动这个现代Web开发中不可或缺的技术,无论你是刷微博、逛知乎还是看脚本,无限滚动都已经渗透到我们日常的浏览体验中,那么,如何优雅地实现它呢?... 目录1. 早期的解决方案2. 交叉观察者:IntersectionObserver2.1 Inter