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

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

相关文章

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

java实现docker镜像上传到harbor仓库的方式

《java实现docker镜像上传到harbor仓库的方式》:本文主要介绍java实现docker镜像上传到harbor仓库的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 前 言2. 编写工具类2.1 引入依赖包2.2 使用当前服务器的docker环境推送镜像2.2

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Java easyExcel实现导入多sheet的Excel

《JavaeasyExcel实现导入多sheet的Excel》这篇文章主要为大家详细介绍了如何使用JavaeasyExcel实现导入多sheet的Excel,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录1.官网2.Excel样式3.代码1.官网easyExcel官网2.Excel样式3.代码

python实现对数据公钥加密与私钥解密

《python实现对数据公钥加密与私钥解密》这篇文章主要为大家详细介绍了如何使用python实现对数据公钥加密与私钥解密,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录公钥私钥的生成使用公钥加密使用私钥解密公钥私钥的生成这一部分,使用python生成公钥与私钥,然后保存在两个文

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

Golang如何用gorm实现分页的功能

《Golang如何用gorm实现分页的功能》:本文主要介绍Golang如何用gorm实现分页的功能方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景go库下载初始化数据【1】建表【2】插入数据【3】查看数据4、代码示例【1】gorm结构体定义【2】分页结构体