文章目录

  • 银行家算法
  • 实验原理
    • 银行家算法中的数据结构
    • 银行家算法
    • 安全性算法
  • 完整代码
  • 测试
    • 测试代码
    • 测试数据
    • 测试结果

银行家算法

银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。(破坏了环路等待条件)


实验原理

银行家算法中的数据结构

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++)相关推荐

  1. 操作系统-银行家算法(Java实现)

    一.银行家算法思想 银行家算法是最著名的死锁避免算法,其思想是:将操作系统视为银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款.操作系统按照银行家制定 ...

  2. [操作系统] 银行家算法

    文章目录 安全序列 通俗理解模型 初始借完钱 分析借钱的安全序列 银行家算法 核心思想 资源表示 安全性算法分析系统状态 银行家算法实现 思路分析 银行家算法步骤 安全性算法步骤 升华思维 安全序列 ...

  3. 计算机操作系统——银行家算法

    1.实验目的: 银行家算法是由Dijkstra设计的最具有代表性的避免死锁的算法.本实验通过编写一个模拟动态资源分配的银行家算法程序,进一步深入理解死锁.产生死锁的必要条件.安全状态等重要概念,并掌握 ...

  4. 操作系统银行家算法模拟实现(C语言版)

    目录 一.实验目的 二.实验内容 三.实验要点说明 银行家算法实例 程序结构 四.实验代码 五.实验运行结果 一.实验目的 通过编写一个模拟动态资源分配的银行家算法程序,进一步深入理解死锁.产生死锁的 ...

  5. 算法分析与设计实验报告 ——二分搜索程序算法的实现

    算法分析与设计实验报告 --二分搜索程序算法的实现 实验目的及要求 1.理解分治算法的概念和基本要素: 2.理解递归的概念: 3.掌握设计有效算法的分治策略: 4.通过二分搜索技术学习分治策略设计技巧 ...

  6. 计算机LCG/PCG/MWC/XorShift等PRNG算法,以及V8中Math.random()、webkit中crypto等随机算法的实现

    计算机LCG/PCG/MWC/XorShift等PRNG算法,以及V8中Math.random().webkit中crypto等随机算法的实现 本文篇幅较长,如想直接看 js 的随机数实现可定位本文E ...

  7. XD现代密码学大作业-欧几里德及其扩展算法的实现

    西电现代密码学大作业1-欧几里德及其扩展算法的实现 一.实验名称:欧几里德及其扩展算法的实现 二.实验原理:学习及其扩展算法. 三.实验目的: 四.实验内容: 五.实验器材(设备.元器件): 六.实验 ...

  8. 商用密码算法的实现(常见的密码算法库)

    1.OpenSSL OpenSSL 是一个开源的密码库,支持许多密码算法和协议的实现,包括 AES.DES.RSA.Diffie-Hellman 等.它还提供了 SSL 和 TLS 协议的实现,用于保 ...

  9. 306-置换策略OPT算法的实现

    置换策略OPT算法的实现 最佳(OPT) OPT策略选择置换下次访问当前时间最长的那些页 可以看出该算法能导致最少的缺页中断,但是由于它要求操作系统必须知道将来的事件.显然这是不可能实现的.但是它仍能 ...

最新文章

  1. EasyTouch初步使用
  2. Android 蓝牙启动流程(以及设置蓝牙为作为sink模式 接收端模式)
  3. javaScript不是java脚本
  4. 20个常用的正则表达式
  5. LeetCode 2049. 统计最高分的节点数目(DFS)
  6. 2021年中国移动游戏行业深度洞察报告
  7. python字典值求和_Python两个字典键同值相加的方法总结
  8. jdba访问mysql_Java中JDBC操作数据库的步骤
  9. 全国地级市坐标、名称、编码获取 / 全球城市坐标位置
  10. Phase2 Day2 数组和链表
  11. 计算机硬件软件基础知识(小白)
  12. tkmybatis详细教程(一篇就明白)
  13. 机械零件设计手册_NASA Fastener Design Manual 紧固件设计手册 - 翻译 2/14
  14. 7款强大的免费PDF批量分割软件【附下载】
  15. php仿qq空间网页源码,516 仿QQ空间网页头部代码
  16. 鸿蒙系统全球发布,鸿蒙系统正式发布,全球瞩目!
  17. 使用Linux训练LoRA模型
  18. 转载分享)移动金融安全风险分析与防护
  19. 将DataFrame中的时间转换为时间戳
  20. 一篇文章让你搞懂,Python文件操作

热门文章

  1. Zuul指定Path+url以及指定可用的服务节点时如何负载均衡
  2. SpringBoot整合 ActiveMQ、SpringBoot整合RabbitMQ、SpringBoot整合Kafka
  3. 原型的指向是否可以改变 原型最终指向了哪里 原型指向改变如何添加方法和访问
  4. 1-100以内的数求和,求出当和第一次大于20的当前数
  5. 【报错笔记】在maven项目中jsp页面使用window.location.href给controller传参时参数过长所以路径无法跳转至controller
  6. 设置二进制或者16/32位的某一位的值
  7. PCB线宽与电流的关系
  8. jdbc详解:1、创建数据库connection连接
  9. 语句的输入和输出 数据类型 运算符
  10. [sh]uniq-sort-awk