操作系统中避免死锁的银行家算法【表面C++实际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]

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

在这里插入图片描述
经演算结果完全正确√

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/443901.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GitHub 使用指南

目录切换分支删除已有文件只删除远程仓库中的文件&#xff0c;不删除本地仓库中的文件同时删除远程仓库和本地仓库中的文件提交文件git查看本地分支连接的是哪个远程分支切换分支 查看本地和远程所有分支 git branch -a当前本地分支为绿色&#xff0c;当前所在分支前带有“*”号…

百度EBG测试部AI测试工程师面经

百度EBG测试部AI测试工程师 1、自我介绍 自我介绍尽量多说一点&#xff0c;她会问你“还有吗&#xff1f;” 2、项目介绍 简历上的项目都让介绍了。会问这个项目是做什么的&#xff0c;是由谁开发&#xff0c;项目如何得到的&#xff0c;在测试过程中实现了什么。 3、自己…

一学就废的并查集它来了

文章目录题目描述输入输出样例输入样例输出提示算法思想代码实现寻找根节点汇总连接情况完整代码关于flag的初值题目描述 某省调查城镇交通状况&#xff0c;得到现有城镇道路统计表&#xff0c;表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城…

一道很简单的贪心算法题~【贪心:我不要脸的伐?】

文章目录题目描述输入输出样例输入样例输出C语言代码实现思路排序处理完整代码C代码实现排序完整代码彩蛋题目描述 小健有一家自己的商店&#xff0c;主营牛奶饮品&#xff0c;最近资金紧张&#xff0c;他想以尽可能低的价格进购足够的牛奶以供日常的需要。所以小健想要求助你…

Eclipse 中修改java编译版本

修改方法是&#xff1a; 1&#xff1a;Preferences-->Java-->Compiler->Compiler compliance level&#xff0c;选择一个需要的版本&#xff0c;比如从默认的1.4改为5.0 2&#xff1a;如果只想修改一个工程的Compiler compliance level,就右单击工程&#xff0c;选择属…

百战c++(1)

Public和private的区别 public和private是类里的关键字&#xff0c;用于规定类内数据或者成员函数的访问权限。private类型的数据或者函数&#xff0c;只能在相应的类内被访问&#xff0c;而public类型的数据或者函数被访问的权限比较宽&#xff0c;还可以在其它类或者其它函数…

一学就废的三种简单排序【冒泡、插入、选择】

文章目录其他排序算法冒泡排序算法实现代码实例插入排序算法实现代码实例选择排序算法实现代码实例其他排序算法 一学就废的归并排序 冒泡排序 排列顺序从前到后或者从后往前都可&#xff0c;本文选择从后到前的顺序&#xff0c;升序排列&#xff1a;比较相邻两个元素&#x…

百战c++(2)

delete 和 delete []的真正区别 delete 对应 new delete[]对应new[]对于简单类型包括简单类型数组&#xff0c;delete 与delete[]没有区别。对于自定义类型数组&#xff0c;delete 只会删除一个元素&#xff0c;delete 则会删除所有元素。 指针和数组的区别 野指针是什么 野指…

shell预先定义的特殊变量

文章目录$#$*$$$# 表示命令行上参数的个数&#xff0c;但不包括shell脚本名本身 为脚本ex1赋予两个变量&#xff0c;测试$#的输出结果 [cmybogon test2]$ . ex1 ma.c mb.c 2 # echo $# 7 # cat $1 $2 $3 | wc -l 2 # echo $#脚本ex1的具体内容 [rootlocalhost test]$ cat ex1…

Linux实验一:常用的Linux命令

文章目录一、实验目的二、实验要求三、实验内容1、系统的使用2、命令的使用3、文件操作4、系统询问与权限口令5、其它常用命令四、实验操作1、基本命令的使用2、文件和目录操作3、创建用户帐户一、实验目的 1、熟悉Linux的桌面环境&#xff1b; 2、了解Linux所安装的软件包 3、…

Linux实验二:vi编辑器的使用

文章目录一、实验目的二、实验要求三、实验内容1、创建文件2、编辑文件一、实验目的 1、练习并掌握Linux提供的vi编辑器来编译C程序 2、学会利用gcc、gdb编译、调试C程序 3、本次实验的目的是让同学们了解如何使用vi编辑器进行创建和编辑文件 二、实验要求 1、文件编辑器vi…

百战c++(os1)

Linux中的锁 互斥锁&#xff1a;mutex&#xff0c;用于保证在任何时刻&#xff0c;都只能有一个线程访问该对象。当获取锁操作失败时&#xff0c;线程会进入睡眠&#xff0c;等待锁释放时被唤醒 读写锁&#xff1a;rwlock&#xff0c;分为读锁和写锁。处于读操作时&#xff0…

Linux实验三:Shell编程

文章目录一、实验目的二、实验要求三、实验内容1、通配符的使用2、重定向3、管道4、shell变量5、建立下面的脚本&#xff0c;运行并分析输出结果&#xff0c;并给出代码注释。6、编写脚本一、实验目的 1.为文件扩展名使用通配符 2.标准输入、标准输出和标准错误的重定向 3.使…

a href=#与 a href=javascript:void(0) 的区别

a href"#"> 点击链接后&#xff0c;页面会向上滚到页首&#xff0c;# 默认锚点为 #TOP<a href"javascript:void(0)" onClick"window.open()"> 点击链接后&#xff0c;页面不动&#xff0c;只打开链接<a href"#" οnclick&…

Linux实验四:编译和调试工具的使用

文章目录一、实验目的&#xff1a;二、实验要求三、实验内容四、实验操作1、用gcc编译程序&#xff0c;写出编译过程&#xff0c;并给出运行结果。2、调试程序&#xff0c;要求用gdb进行调试并给出修改方案。3、make的使用一、实验目的&#xff1a; 1、练习并掌握Linux提供的v…

Linux实验五:Linux环境下的C语言编程

文章目录一、实验目的&#xff1a;二、实验要求三、实验内容1、编写一段C语言程序使其完成&#xff1a;父进程创建两个子进程&#xff0c;每个进程都在屏幕上显示自己的进程ID号。2、上机调试下面的程序&#xff0c;观察运行结果&#xff0c;分析原因。3、利用两个管道进行双向…

百战c++(4)

1.求下面函数的返回值&#xff08;微软&#xff09; int func(x) { int countx 0; while(x) { countx ; x x&(x-1); } return countx; } 假定x 9999。 答案&#xff1a;8 思路&#xff1a;将x转化为2进制&#xff0c;看含有的1的个数。 2. 什么是“引用”&…

ndarray对象的建立

文章目录ndarray&#xff08;别名array&#xff09;常用属性创建NumPy数组使用array()函数使用zeros()函数使用ones()函数使用empty()函数使用arange()函数注意ndarray&#xff08;别名array&#xff09; 常用属性 import numpy as np # Numpy工具包data np.arange(12).res…

百战c++(5)

11. 已知strcpy的函数原型&#xff1a;char *strcpy(char *strDest, const char *strSrc)其中strDest 是目的字符串&#xff0c;strSrc 是源字符串。不调用C/C 的字符串库函数&#xff0c;请编写函数 strcpy。 答案&#xff1a; char *strcpy(char *strDest, const char *strS…

Numpy数组的广播机制

文章目录前言数组广播广播机制的使用条件前言 Numpy数组不需要循环遍历&#xff0c;即可对每个元素执行批量的算术运算操作&#xff08;矢量化运算&#xff09;。当两个数组大小&#xff08;Numpy.shape&#xff09;不同时&#xff0c;进行算术运算会出现广播机制。 数组广播…