文章目录

  • 银行家算法
  • 实验原理
    • 数据结构
    • 初始化
    • 输出资源分配量
    • 安全性算法
    • 银行家算法
  • 完整代码
  • 测试数据
  • 测试结果
    • 第一题
    • 第二题

银行家算法

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


实验原理


数据结构

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]

int Allocation[11][101];//进程已获得资源
int Max[11][101];//进程所需最大资源
int Available[11];//可分配资源
int Need[11][101];//进程所需资源
int Requesti[11];//资源请求
int Work[11];//工作向量
int link[11];//安全序列
int x,y;//x表进程数,y表资源种类

初始化

帮助用户输入已知变量的函数,构建银行家算法的Max、Allocation、Need、Available矩阵,便于进行接下来的数据处理。

void init(){//初始化cout << "请输入进程个数:" << endl;cin >> x;cout << "请输入资源共有多少类:" << endl;cin >> y;cout << "请输入每个进程所需要的各种资源的最大数目:" << endl;for (int i = 0; i < x; i++) {cout << "P" << i+1 << ":" ;for (int j = 0; j < y; j++) {cin >> Max[i][j];}}cout << "请输入每个进程已分配的资源数量:" << endl;for(int i=0; i<x; i++){cout << "P" << i+1 << ":" ;for(int j=0; j<y; j++){cin >> Allocation[i][j];if(Allocation[i][j]>Max[i][j]){cout << "已分配资源数量大于进程所需的资源最大数目,请重新输入" << endl;i--;}}}cout << "请输入系统可分配的资源数:" << endl;for (int i = 0; i < y; i++) {cin >> Available[i];}for (int i = 0; i < x; i++) {//计算每一个进程尚需的各类资源数,Need矩阵for (int j = 0; j < y; j++) {Need[i][j] = Max[i][j] - Allocation[i][j];}}
}

输出资源分配量

打印现在的矩阵状态(Max、Allocation、Need、Available),方便用户了解算法进行程度

void printSystemVariable(){//输出资源分配量cout << "此时资源分配量如下:" << endl;cout << "进程  " << "   Max   " << "   Alloction " << "    Need  " << "    Available " << endl;for(int i=0;i<x;i++){//第i个进程cout << "P" << i+1 << "     " ;for(int j=0;j<y;j++){//第i个进程的Max矩阵信息cout << Max[i][j] << "    " ;}cout << "|  " ;for(int j=0;j<y;j++){//第i个进程的Allocation矩阵信息cout << Allocation[i][j] << "    " ;}cout << "|  " ;for(int j=0;j<y;j++){//第i个进程的Need矩阵信息cout << Need[i][j] << "    " ;}cout << "|  " ;if(i==0){for(int j=0;j<y;j++){//第i个进程的Available矩阵信息cout << Available[j] << "    " ;}}cout << endl ;}
}

安全性算法

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 chesksafe(){//安全性算法for (int i = 0; i < y; i++) {Work[i] = Available[i];}bool Finish[7];//工作向量int mark = x;//避免改变x的值所设的变量int temp = 0;//满足需求资源少于剩余资源这一条件的资源数int flag = 0;//进行资源分配的次数while (mark--) {//求安全序列的操作最多进行进程数次for(int i=0;i<x;++i){//判定第i个进程if(Finish[i]==true){continue;}for (int j = 0; j < y; j++) {if(Need[i][j]<=Work[j]){//计算该进程需求资源少于剩余资源的资源数temp++;}}if(temp==y){//全部资源都满足需求资源少于剩余资源for (int j = 0; j < y; j++) {//获得分配给该资源的资源数Work[j]+=Allocation[i][j];}Finish[i]=true;flag++;//进行一次资源分配link[flag]=i+1;//将进行资源分配的进程依次放入队列}temp=0;//更新满足分配资源条件的资源数}}if(flag==x){//如果没有进行进程数次资源分配,说明不是安全序列cout << "系统处于安全状态,安全序列为:" << endl;for (int i = 1; i <= x; i++) {cout << "P" << link[i] << " " ;}cout << endl;return true;}else{cout << "系统处于不安全状态" << endl;return false;}
}

银行家算法

设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等待。

  string an;//存储是否请求分配的用户指令bool flag = false;//用于跳出两层循环的标志while(1){cout << "是否请求分配?('y'or'Y'表是,'n'or'N'表否) " ;cin>>an;if(an[0]!='Y'&&an[0]!='y'){break;}int num;cout << "请输入请求资源的进程号(如:P1则输入1): " << endl;cin >> num;num -= 1;//进程从1开始计数但各个数组下标从0开始计数cout << "输入进程请求的资源数" << endl;for (int i = 0; i < y; i++) {cin >> Requesti[i];}for (int i = 0; i < y; i++) {if(Requesti[i]>Need[num][i]){cout << "所需要的资源数已超过所宣布最大值Max" << endl;flag = true;break;}if(Requesti[i]>Available[i]){cout << "尚无足够资源" << endl;flag = true;break;}Available[i]-=Requesti[i];Allocation[num][i]+=Requesti[i];Need[num][i]-=Requesti[i];}if (flag){//当任意资源请求出现问题时,跳出两层循环flag = false;//更新标志continue;//执行下一次循环}int temp = 0;//满足Max值的Allocation值的个数if(chesksafe()){//安全,完成本次分配for (int i = 0; i < y; i++) {if(Allocation[num][i]>=Max[num][i]){temp++;}}if (temp == y) {/*如果1个进程分配资源后,每个资源已获得值都大于等于所需最大值则更新Available、Allocation和Need矩阵*/for (int i = 0; i < y; i++) {Available[i]+=Allocation[num][i];//可分配资源获得该进程已获得的资源数Allocation[num][i]=0;//清空该进程已获得的资源数Need[num][i]=0;//清空该进程尚需的各类资源数}}cout << "分配成功" << endl;printSystemVariable();}else{//不安全,撤销之前的操作cout << "分配失败" << endl;for (int i = 0; i < y; i++) {Available[i]+=Requesti[i];Need[num][i]+=Requesti[i];Allocation[num][i]-=Requesti[i];}printSystemVariable();}}

完整代码

#include <iostream>
using namespace std;int Allocation[11][101];//进程已获得资源
int Max[11][101];//进程所需最大资源
int Available[11];//可分配资源
int Need[11][101];//进程所需资源
int Requesti[11];//资源请求
int Work[11];//工作向量
int link[11];//安全序列
int x,y;//x表进程数,y表资源种类void init();//初始化
void printSystemVariable();//输出资源分配量
bool chesksafe();//安全性算法int main(int argc, char const *argv[]) {init();printSystemVariable();if(!chesksafe()){return 0;}string an;//存储是否请求分配的用户指令bool flag = false;//用于跳出两层循环的标志while(1){cout << "是否请求分配?('y'or'Y'表是,'n'or'N'表否) " ;cin>>an;if(an[0]!='Y'&&an[0]!='y'){break;}int num;cout << "请输入请求资源的进程号(如:P1则输入1): " << endl;cin >> num;num -= 1;//进程从1开始计数但各个数组下标从0开始计数cout << "输入进程请求的资源数" << endl;for (int i = 0; i < y; i++) {cin >> Requesti[i];}for (int i = 0; i < y; i++) {if(Requesti[i]>Need[num][i]){cout << "所需要的资源数已超过所宣布最大值Max" << endl;flag = true;break;}if(Requesti[i]>Available[i]){cout << "尚无足够资源" << endl;flag = true;break;}Available[i]-=Requesti[i];Allocation[num][i]+=Requesti[i];Need[num][i]-=Requesti[i];}if (flag){//当任意资源请求出现问题时,跳出两层循环flag = false;//更新标志continue;//执行下一次循环}int temp = 0;//满足Max值的Allocation值的个数if(chesksafe()){//安全,完成本次分配for (int i = 0; i < y; i++) {if(Allocation[num][i]>=Max[num][i]){temp++;}}if (temp == y) {/*如果1个进程分配资源后,每个资源已获得值都大于等于所需最大值则更新Available、Allocation和Need矩阵*/for (int i = 0; i < y; i++) {Available[i]+=Allocation[num][i];//可分配资源获得该进程已获得的资源数Allocation[num][i]=0;//清空该进程已获得的资源数Need[num][i]=0;//清空该进程尚需的各类资源数}}cout << "分配成功" << endl;printSystemVariable();}else{//不安全,撤销之前的操作cout << "分配失败,撤销本次操作" << endl;for (int i = 0; i < y; i++) {Available[i]+=Requesti[i];Need[num][i]+=Requesti[i];Allocation[num][i]-=Requesti[i];}printSystemVariable();}}return 0;
}void init(){//初始化cout << "请输入进程个数:" << endl;cin >> x;cout << "请输入资源共有多少类:" << endl;cin >> y;cout << "请输入每个进程所需要的各种资源的最大数目:" << endl;for (int i = 0; i < x; i++) {cout << "P" << i+1 << ":" ;for (int j = 0; j < y; j++) {cin >> Max[i][j];}}cout << "请输入每个进程已分配的资源数量:" << endl;for(int i=0; i<x; i++){cout << "P" << i+1 << ":" ;for(int j=0; j<y; j++){cin >> Allocation[i][j];if(Allocation[i][j]>Max[i][j]){cout << "已分配资源数量大于进程所需的资源最大数目,请重新输入" << endl;i--;}}}cout << "请输入系统可分配的资源数:" << endl;for (int i = 0; i < y; i++) {cin >> Available[i];}for (int i = 0; i < x; i++) {//计算每一个进程尚需的各类资源数,Need矩阵for (int j = 0; j < y; j++) {Need[i][j] = Max[i][j] - Allocation[i][j];}}
}void printSystemVariable(){//输出资源分配量cout << "此时资源分配量如下:" << endl;cout << "进程  " << "   Max   " << "   Alloction " << "    Need  " << "    Available " << endl;for(int i=0;i<x;i++){//第i个进程cout << "P" << i+1 << "     " ;for(int j=0;j<y;j++){//第i个进程的Max矩阵信息cout << Max[i][j] << "    " ;}cout << "|  " ;for(int j=0;j<y;j++){//第i个进程的Allocation矩阵信息cout << Allocation[i][j] << "    " ;}cout << "|  " ;for(int j=0;j<y;j++){//第i个进程的Need矩阵信息cout << Need[i][j] << "    " ;}cout << "|  " ;if(i==0){for(int j=0;j<y;j++){//第i个进程的Available矩阵信息cout << Available[j] << "    " ;}}cout << endl ;}
}bool chesksafe(){//安全性算法for (int i = 0; i < y; i++) {Work[i] = Available[i];}bool Finish[7];//工作向量int mark = x;//避免改变x的值所设的变量int temp = 0;//满足需求资源少于剩余资源这一条件的资源数int flag = 0;//进行资源分配的次数while (mark--) {//求安全序列的操作最多进行进程数次for(int i=0;i<x;++i){//判定第i个进程if(Finish[i]==true){continue;}for (int j = 0; j < y; j++) {if(Need[i][j]<=Work[j]){//计算该进程需求资源少于剩余资源的资源数temp++;}}if(temp==y){//全部资源都满足需求资源少于剩余资源for (int j = 0; j < y; j++) {//获得分配给该资源的资源数Work[j]+=Allocation[i][j];}Finish[i]=true;flag++;//进行一次资源分配link[flag]=i+1;//将进行资源分配的进程依次放入队列}temp=0;//更新满足分配资源条件的资源数}}if(flag==x){//如果没有进行进程数次资源分配,说明不是安全序列cout << "系统处于安全状态,安全序列为:" << endl;for (int i = 1; i <= x; i++) {cout << "P" << link[i] << " " ;}cout << endl;return true;}else{cout << "系统处于不安全状态" << endl;return false;}
}

测试数据

这里的测试数据就拿教材上的一个习题


测试结果

第一题

第二题

注意题中排序从0开始,程序排序从1开始,此题中的P2对应程序中的P3,输入数字应该是3而不是2


经演算结果完全正确√

操作系统中避免死锁的银行家算法【表面C++实际C语言】一学就废的菜鸡代码相关推荐

  1. 计算机操作系统:实验2 【银行家算法】

    计算机操作系统:实验2 [银行家算法] 文章目录 计算机操作系统:实验2 [银行家算法] 一.前言 二.实验目的 三.实验环境 四.实验内容 五.实验说明 六.实验步骤 1. 认真理解好课本中银行家算 ...

  2. 皮卡丘忠实粉丝之Web实现操作系统实验(进程调度+存储管理+死锁避免银行家算法)

    **皮卡皮卡丘~~~~~~** 目录 进程调度 目的和要求 内容与步骤 运行结果 问题及心得 C语言实现代码 存储管理 目的和要求 内容与步骤 运行结果 问题及心得 C语言实现代码 死锁避免银行家算法 ...

  3. 操作系统-进程死锁:银行家算法

    文章目录 进程死锁:银行家算法 问题描述 实验环境 输入 输出 测试数据 实验设计 数据结构 主要函数功能和参数 系统框架图 流程图 实验结果与分析 结果展示与描述 结果分析 总结 源代码 进程死锁: ...

  4. 《操作系统》实验四:预防进程死锁的银行家算法

    [实验题目]:预防进程死锁的银行家算法 [实验学时]:4学时 [实验目的] 通过这次实验,加深对进程死锁的理解,进一步掌握进程资源的分配.死锁的检测和安全序列的生成方法. [实验内容] 问题描述: 设 ...

  5. 【避免进程死锁】银行家算法

    一.概述 银行家算法(Banker's Algorithm)是一个避免进程死锁的著名算法,由 Dijkstra 于 1965 年提出.本文为笔者的读书笔记,结构如下: 死锁 银行家算法 例子展示 补充 ...

  6. 避免死锁: 银行家算法

    避免死锁: 银行家算法 1.背景 在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还.银行家在客户申请的贷款数量不超 ...

  7. 操作系统中的死锁_操作系统中的死锁介绍

    操作系统中的死锁 1.1究竟什么是僵局? (1.1 What exactly is a deadlock?) In a multiprogramming environment, there may ...

  8. 避免死锁的银行家算法

    死锁的定义> 如果一组进程中的每一个进程都在等待仅由该组进程中的其他进程才能引发的事件,那仫该组进程就是死锁的. 产生死锁的必要条件> 1).互斥条件:进程对所分配到的资源进行排它性使用, ...

  9. 操作系统之进程管理:19、死锁的处理策略:避免死锁(银行家算法)

    19.死锁的处理策略:避免死锁 思维导图 安全序列 例 银行家算法实现步骤 银行家算法的实现 思维导图 安全序列 来看这样的情况: 由上述表格可知,B仍需50,A仍需30,T仍需20,我手中剩余40 ...

最新文章

  1. 用animation的steps属性制作帧动画
  2. 200 行代码实现 2048 游戏
  3. [51nod1079]中国剩余定理
  4. 【springboot】静态资源设置缓存时间
  5. 修改Windows远程登录端口号
  6. 【openMV】算法矫正镜头+视频格式对应的分辨率
  7. es6 let和const命令(1)
  8. 告诉你一个 AtomicInteger 的惊天大秘密!
  9. VS2010 MVC的 安装
  10. mysql序列号生成软件_mysql 序列号生成器
  11. JS全国城市数组列表
  12. 相机像素尺寸(像元大小)和成像系统分辨率之间的关系
  13. 计算机连接打印机连接打印机,怎么连接打印机.教您怎么连接打印机
  14. ionic:点击某个商品名称,跳转到相应的商品详情页面
  15. 51单片机和LCD1602实现简单的密码锁
  16. EN 16034门窗及配件—CE认证
  17. 对C++库链接的认识
  18. win10系统输入法图标不见了怎么找回
  19. 离散数学-集合:1.集合的基本概念
  20. 关于解决电脑有网络但是浏览器却打不开的解决方法

热门文章

  1. 奖学金设计mysql_基于JAVA的奖学金评定系统设计与实现(MySQL)(含录像)
  2. 10以内的分解与组成怎么教_【一年级数学】(上)10以内的分与合技巧及练习题...
  3. e站app改内置hosts_米家踢脚线电暖器E评测:符合现代家居审美 全屋取暖“小钢炮”...
  4. @value 静态变量_Java中的变量——通过示例学习Java编程(4)
  5. mapgis转arcgis数据后发现属性表内没有数据
  6. 神经网络与深度学习——TensorFlow2.0实战(笔记)(二)(安装TensorFlow2.0)
  7. 【转】C#中枚举类型与静态变量
  8. ABP入门系列(19)——使用领域事件
  9. 【转】[SharePoint 开发详解] 一个Feature中使用SPGridView的几个Tips
  10. 一步步编写操作系统 2 部署工作环境 2