操作系统 :银行家算法的实现(C++)
文章目录
- 银行家算法
- 实验原理
- 银行家算法中的数据结构
- 银行家算法
- 安全性算法
- 完整代码
- 测试
- 测试代码
- 测试数据
- 测试结果
银行家算法
银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。(破坏了环路等待条件)
实验原理
银行家算法中的数据结构
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]
这里我用到的数据结构成员变量
std::vector<std::string> _ResouceName; //资源名std::vector<int> _available; //系统可利用的各类资源数目std::vector< std::vector<int >> _max; //每一个进程对各种资源的最大需求std::vector< std::vector<int >> _allocation; //系统中每一类资源当前已分配给每一进程的资源数std::vector< std::vector<int >> _need; //每一个进程尚需的各类资源数std::vector<int> _Security; //安全序列size_t _processNum; //进程数size_t _resouceNum; //资源数
银行家算法
设Requesti是进程Pi的请求向量,如果Requesti[j]=K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:
(1)如果Requesti[j]≤Need[i,j],便转向步骤(2);否则认为出错,因为它所需要的资源数已超过它所宣布最大值。
(2)如果Requesti[j]≤Available[j],便转向步骤(3);否则,表示尚无足够资源,Pi须等待。
(3)系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:
Available[j]=Available[j]-Requesti[j];
Allocation[i,j]=Allocation[i,j]+Requesti[j];
Need[i,j]=Need[i,j]-Requesti[j];
系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。
bool CheckRequest(size_t pid, std::vector<int> request){//检查资源请求是否合理for (size_t i = 0; i < _resouceNum; i++){//需求资源数已经超过最大值if (request[i] > _need[pid][i]){std::cout << "需求资源数已经超过最大值" << std::endl;return false;}//尚无足够资源if (request[i] > _available[i]){std::cout << "尚无足够资源,进程等待" << std::endl;return false;} }//尝试分配资源给进程,看看此次分配后系统是否处于安全状态for (size_t i = 0; i < _resouceNum; i++){_available[i] -= request[i];_allocation[pid][i] += request[i];_need[pid][i] -= request[i];}//检查分配后系统是否安全if (CheckSafe() == true){//分配后系统安全,正式分配std::cout << "本次资源" << pid << "分配成功" << std::endl;OutPut();return true;}else{//分配后不安全,分配失效,资源恢复std::cout << "本次资源分配后系统不安全,分配作废" << std::endl;for (size_t i = 0; i < _resouceNum; i++){_available[i] += request[i];_allocation[pid][i] -= request[i];_need[pid][i] += request[i];}OutPut();return false;}}
安全性算法
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[i]+Allocation[i,j];
Finish[i]=true;
go to step 2;
4)如果所有进程的Finish[i]=true都满足, 则表示系统处于安全状态;否则,系统处于不安全状态
//安全性算法bool CheckSafe(){std::vector<int> work(_available); //表示系统可提供给进程继续运行所需的各类资源数目std::vector<bool> finish(_processNum, false); //表示系统是否有足够的资源分配给该进程while (1){size_t i = 0;//检查是否全部都处于安全状态for (i = 0; i < _processNum; i++){if(finish[i] == false)break;}//如果全都处于安全状态,则说明此时系统也处于安全状态if (i == _processNum){std::cout << "系统此时安全" << std::endl;return true;}for (i = 0; i < _processNum; i++){//如果这个进程已经执行过,则跳过if (finish[i] == true){continue;}//标志当前进程分配资源后是否安全bool flag = true;for (size_t j = 0; j < _resouceNum; j++){//如果某一项资源不够分配,则说明当前进程不能执行,继续判断后面的if (_need[i][j] > work[j]){flag = false;break;}}if (flag == true){std::cout << "执行进程" << i << " ,系统可利用资源更新" << std::endl;//加入安全序列中_Security.push_back(i);//调用进程运行,并且释放进程所占资源for (size_t j = 0; j < _resouceNum; j++){work[j] += _allocation[i][j];finish[i] = true;std::cout << "可用资源"<< _ResouceName[j] << "更新为: " << work[j] << std::endl;}break;//调用完后进入下一轮查找安全进程}}//如果进程全部遍历完也没有任何一个执行,则说明此时无法分配,不安全if (i == _processNum){std::cout << "系统此时不安全" << std::endl;return false;} }}
完整代码
#include<iostream>
#include<string>
#include<vector>class Banker
{public:friend Banker* Input(); //输入函数 std::vector<std::string> _ResouceName; //资源名Banker(std::vector<std::string> ResouceName, std::vector<int> available, std::vector< std::vector<int >> max, std::vector< std::vector<int >> allocation): _ResouceName(ResouceName), _available(available), _max(max), _allocation(allocation), _need(_max.size(), std::vector<int>(_max[0].size(), 0)), _processNum(_max.size()), _resouceNum(_max[0].size()){//计算出需要的资源数for (size_t i = 0; i < _processNum; i++){ for (size_t j = 0; j < _resouceNum; j++){_need[i][j] = _max[i][j] - _allocation[i][j];}}}//封装给外界获取数量的接口int ResouceNum() const{return _resouceNum;}int ProcessNum() const{return _processNum;}//输出安全序列void printSecurity(){std::cout << "--------------" << std::endl;std::cout << "安全序列为: " ;for (auto it : _Security){std::cout << it << std::ends;}std::cout << "--------------" << std::endl;std::cout << std::endl;}//输出函数void OutPut(){std::cout << "*************************************" << std::endl;std::cout << "当前进程数:" << _processNum << " 当前资源种类数量:" << _resouceNum << std::endl;for (size_t i = 0; i < _resouceNum; i++){std::cout << "资源" << _ResouceName[i] << "可用数量为: " << _available[i] << std::endl;}std::cout << "--------------" << std::endl;for (size_t i = 0; i < _processNum; i++){std::cout << "进程" << i << std::endl;for (size_t j = 0; j < _resouceNum; j++){std::cout << "资源" << _ResouceName[j] << " 最大需求数量为: " << _max[i][j] << " 当前分配数量为: " << _allocation[i][j] << " 剩余需求数量为: " << _need[i][j] << std::endl;}}std::cout << "*************************************" << std::endl;}//银行家算法核心,判断请求算法bool CheckRequest(size_t pid, std::vector<int> request){//检查资源请求是否合理for (size_t i = 0; i < _resouceNum; i++){//需求资源数已经超过最大值if (request[i] > _need[pid][i]){std::cout << "需求资源数已经超过最大值" << std::endl;return false;}//尚无足够资源if (request[i] > _available[i]){std::cout << "尚无足够资源,进程等待" << std::endl;return false;} }//尝试分配资源给进程,看看此次分配后系统是否处于安全状态for (size_t i = 0; i < _resouceNum; i++){_available[i] -= request[i];_allocation[pid][i] += request[i];_need[pid][i] -= request[i];}//检查分配后系统是否安全if (CheckSafe() == true){//分配后系统安全,正式分配std::cout << "本次资源" << pid << "分配成功" << std::endl;OutPut();return true;}else{//分配后不安全,分配失效,资源恢复std::cout << "本次资源分配后系统不安全,分配作废" << std::endl;for (size_t i = 0; i < _resouceNum; i++){_available[i] += request[i];_allocation[pid][i] -= request[i];_need[pid][i] += request[i];}OutPut();return false;}}//安全性算法bool CheckSafe(){std::vector<int> work(_available); //表示系统可提供给进程继续运行所需的各类资源数目std::vector<bool> finish(_processNum, false); //表示系统是否有足够的资源分配给该进程while (1){size_t i = 0;//检查是否全部都处于安全状态for (i = 0; i < _processNum; i++){if(finish[i] == false)break;}//如果全都处于安全状态,则说明此时系统也处于安全状态if (i == _processNum){std::cout << "系统此时安全" << std::endl;return true;}for (i = 0; i < _processNum; i++){//如果这个进程已经执行过,则跳过if (finish[i] == true){continue;}//标志当前进程分配资源后是否安全bool flag = true;for (size_t j = 0; j < _resouceNum; j++){//如果某一项资源不够分配,则说明当前进程不能执行,继续判断后面的if (_need[i][j] > work[j]){flag = false;break;}}if (flag == true){std::cout << "执行进程" << i << " ,系统可利用资源更新" << std::endl;//加入安全序列中_Security.push_back(i);//调用进程运行,并且释放进程所占资源for (size_t j = 0; j < _resouceNum; j++){work[j] += _allocation[i][j];finish[i] = true;std::cout << "可用资源"<< _ResouceName[j] << "更新为: " << work[j] << std::endl;}break;//调用完后进入下一轮查找安全进程}}//如果进程全部遍历完也没有任何一个执行,则说明此时无法分配,不安全if (i == _processNum){std::cout << "系统此时不安全" << std::endl;return false;} }}private:std::vector<int> _available; //系统可利用的各类资源数目std::vector< std::vector<int >> _max; //每一个进程对各种资源的最大需求std::vector< std::vector<int >> _allocation; //系统中每一类资源当前已分配给每一进程的资源数std::vector< std::vector<int >> _need; //每一个进程尚需的各类资源数std::vector<int> _Security; //安全序列size_t _processNum; //进程数size_t _resouceNum; //资源数
};//输入函数
Banker* Input()
{size_t processNum, resouceNum;std::cout << "请输入进程数量:" << std::endl;std::cin >> processNum;std::cout << "请输入资源种类数量:" << std::endl;std::cin >> resouceNum;std::vector<std::string> ResouceName(resouceNum);std::vector<int> available(resouceNum);std::vector< std::vector<int >> max(processNum, std::vector<int>(resouceNum, 0));std::vector< std::vector<int >> allocation(processNum, std::vector<int>(resouceNum, 0));std::cout << "请输入资源名:" << std::endl;for (size_t i = 0; i < resouceNum; i++){std::cin >> ResouceName[i];}std::cout << "请输入系统中该资源空闲数量:" << std::endl;for (size_t i = 0; i < resouceNum; i++){std::cin >> available[i];}for (size_t i = 0; i < processNum; i++){std::cout << "请输入进程" << i << "中资源的最大需求量:" << std::endl;for (size_t j = 0; j < resouceNum; j++){ std::cin >> max[i][j];}}for (size_t i = 0; i < processNum; i++){std::cout << "请输入进程" << i << "中资源的已分配数量:" << std::endl;for (size_t j = 0; j < resouceNum; j++){ std::cin >> allocation[i][j];}}std::cout << "资源输入完毕" << std::endl;std::cout << "--------------" << std::endl;Banker* banker = new Banker(ResouceName, available, max, allocation);return banker;
}
测试
测试代码
#include"Banker.hpp"
using namespace std;void test()
{int flag = 0;Banker* backup = Input();bool result;while (1){Banker banker = *backup;cout << "--------------------" << endl;cout << "1.判断当前系统状态" << endl;cout << "2.申请资源" << endl;cout << "0.退出" << endl;cout << "--------------------" << endl;cin >> flag;switch (flag){case 1:{result = banker.CheckSafe();break;}case 2:{size_t pid;vector<int> request(banker.ResouceNum(), 0);cout << "请输入发起请求的进程号:" << endl;cin >> pid;cout << "请输入请求的资源的数量:" << endl;for (size_t i = 0; i < request.size(); i++){cin >> request[i];}result = banker.CheckRequest(pid, request);break;}case 0:exit(0);default:cout << "请输入正确选项" << endl;continue;}if (result == true){cout << "资源分配成功, 系统此时安全" << endl;banker.printSecurity();}else{cout << "资源分配失败,此时不安全" << endl;}}
}int main()
{test();
}
测试数据
这里的测试数据就拿教材上的一个习题
测试结果
可以看到,结果完全正确。
操作系统 :银行家算法的实现(C++)相关推荐
- 操作系统-银行家算法(Java实现)
一.银行家算法思想 银行家算法是最著名的死锁避免算法,其思想是:将操作系统视为银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款.操作系统按照银行家制定 ...
- [操作系统] 银行家算法
文章目录 安全序列 通俗理解模型 初始借完钱 分析借钱的安全序列 银行家算法 核心思想 资源表示 安全性算法分析系统状态 银行家算法实现 思路分析 银行家算法步骤 安全性算法步骤 升华思维 安全序列 ...
- 计算机操作系统——银行家算法
1.实验目的: 银行家算法是由Dijkstra设计的最具有代表性的避免死锁的算法.本实验通过编写一个模拟动态资源分配的银行家算法程序,进一步深入理解死锁.产生死锁的必要条件.安全状态等重要概念,并掌握 ...
- 操作系统银行家算法模拟实现(C语言版)
目录 一.实验目的 二.实验内容 三.实验要点说明 银行家算法实例 程序结构 四.实验代码 五.实验运行结果 一.实验目的 通过编写一个模拟动态资源分配的银行家算法程序,进一步深入理解死锁.产生死锁的 ...
- 算法分析与设计实验报告 ——二分搜索程序算法的实现
算法分析与设计实验报告 --二分搜索程序算法的实现 实验目的及要求 1.理解分治算法的概念和基本要素: 2.理解递归的概念: 3.掌握设计有效算法的分治策略: 4.通过二分搜索技术学习分治策略设计技巧 ...
- 计算机LCG/PCG/MWC/XorShift等PRNG算法,以及V8中Math.random()、webkit中crypto等随机算法的实现
计算机LCG/PCG/MWC/XorShift等PRNG算法,以及V8中Math.random().webkit中crypto等随机算法的实现 本文篇幅较长,如想直接看 js 的随机数实现可定位本文E ...
- XD现代密码学大作业-欧几里德及其扩展算法的实现
西电现代密码学大作业1-欧几里德及其扩展算法的实现 一.实验名称:欧几里德及其扩展算法的实现 二.实验原理:学习及其扩展算法. 三.实验目的: 四.实验内容: 五.实验器材(设备.元器件): 六.实验 ...
- 商用密码算法的实现(常见的密码算法库)
1.OpenSSL OpenSSL 是一个开源的密码库,支持许多密码算法和协议的实现,包括 AES.DES.RSA.Diffie-Hellman 等.它还提供了 SSL 和 TLS 协议的实现,用于保 ...
- 306-置换策略OPT算法的实现
置换策略OPT算法的实现 最佳(OPT) OPT策略选择置换下次访问当前时间最长的那些页 可以看出该算法能导致最少的缺页中断,但是由于它要求操作系统必须知道将来的事件.显然这是不可能实现的.但是它仍能 ...
最新文章
- EasyTouch初步使用
- Android 蓝牙启动流程(以及设置蓝牙为作为sink模式 接收端模式)
- javaScript不是java脚本
- 20个常用的正则表达式
- LeetCode 2049. 统计最高分的节点数目(DFS)
- 2021年中国移动游戏行业深度洞察报告
- python字典值求和_Python两个字典键同值相加的方法总结
- jdba访问mysql_Java中JDBC操作数据库的步骤
- 全国地级市坐标、名称、编码获取 / 全球城市坐标位置
- Phase2 Day2 数组和链表
- 计算机硬件软件基础知识(小白)
- tkmybatis详细教程(一篇就明白)
- 机械零件设计手册_NASA Fastener Design Manual 紧固件设计手册 - 翻译 2/14
- 7款强大的免费PDF批量分割软件【附下载】
- php仿qq空间网页源码,516 仿QQ空间网页头部代码
- 鸿蒙系统全球发布,鸿蒙系统正式发布,全球瞩目!
- 使用Linux训练LoRA模型
- 转载分享)移动金融安全风险分析与防护
- 将DataFrame中的时间转换为时间戳
- 一篇文章让你搞懂,Python文件操作
热门文章
- Zuul指定Path+url以及指定可用的服务节点时如何负载均衡
- SpringBoot整合 ActiveMQ、SpringBoot整合RabbitMQ、SpringBoot整合Kafka
- 原型的指向是否可以改变 原型最终指向了哪里 原型指向改变如何添加方法和访问
- 1-100以内的数求和,求出当和第一次大于20的当前数
- 【报错笔记】在maven项目中jsp页面使用window.location.href给controller传参时参数过长所以路径无法跳转至controller
- 设置二进制或者16/32位的某一位的值
- PCB线宽与电流的关系
- jdbc详解:1、创建数据库connection连接
- 语句的输入和输出 数据类型 运算符
- [sh]uniq-sort-awk