银行家算法的模拟与死锁避免

news/2024/11/29 12:31:05/

什么是死锁

死锁(Deadlock)是指在多进程系统中,每个进程都在等待其他进程释放所占用的资源,导致系统无法继续执行下去的一种状态。

死锁通常发生在多个进程同时竞争有限的资源,并且每个进程都在等待其他进程释放资源,同时又不释放自己所占有的资源,从而导致所有进程都无法继续执行下去,形成了死锁状态。

死锁产生的条件通常被称为死锁的必要条件,包括以下四个条件:

  1. 互斥条件(Mutual Exclusion):一个资源每次只能被一个进程占用,即在一段时间内只能由一个进程独占使用。
  2. 请求与保持条件(Hold and Wait):一个进程在申请新的资源的同时保持对已占有资源的不释放。
  3. 不剥夺条件(No Preemption):系统不能抢占进程所占用的资源,只能由进程自愿释放。
  4. 环路等待条件(Circular Wait):存在一个进程资源的循环链,使得每个进程都在等待下一个进程所占用的资源。

当这四个条件同时满足时,就有可能发生死锁。死锁的发生会导致系统停滞,进程无法继续执行,资源无法被有效利用,影响系统的可用性和性能。

为了避免死锁的发生,可以采取多种方法,包括资源分配策略、死锁检测与恢复、死锁预防和死锁避免等。其中,银行家算法就是一种用于死锁避免的资源分配算法,通过合理地控制资源分配,预防系统进入死锁状态。

什么是银行家算法

在多进程环境中,每个进程都需要申请一定数量的资源才能完成其任务。银行家算法通过对进程的资源请求进行检查和控制,保证系统能够分配资源而不会导致死锁的发生。

银行家算法基于以下假设:

  1. 每个进程在开始执行之前必须声明其最大需求资源量。
  2. 每个进程在执行过程中不会改变其最大需求资源量。
  3. 每个进程可以一次性申请并获得其所需的全部资源。
  4. 资源分配是有限制的,系统中的资源总量是固定的。

银行家算法的核心思想是,系统在分配资源之前先进行安全性检查,确保分配资源后系统仍然能够达到安全状态,即不会发生死锁。如果某个进程的资源请求导致系统进入不安全状态,那么该请求将被延迟,直到系统再次进入安全状态才能分配资源给该进程。

通过合理的资源分配和安全性检查,银行家算法可以有效地避免死锁问题,并确保系统的稳定性和可靠性。它在操作系统和并发编程中被广泛应用。

代码实现

思路:
对进程的资源请求进行合法性检查;若请求合法,则进行试分配。试探性分配后,调用安全性算法进行安全性检查。若安全,则满足该进程请求,分配资源;若不安全,则拒绝该进程申请,不分配资源,并恢复系统试分配前的资源状态。
代码:

#include<stdio.h>
#define MAXPROCESS 50
#define MAXRESOURCE 100
int AVAILABLE[MAXRESOURCE];  //可用资源数组
int MAX[MAXPROCESS][MAXRESOURCE]; //最大需求矩阵 
int ALLOCATION[MAXPROCESS][MAXRESOURCE]; //分配矩阵
int NEED [MAXPROCESS][MAXRESOURCE];//需求矩阵
int REQUEST [MAXPROCESS][MAXRESOURCE]; //进程需要资源数 
bool FINISH[MAXPROCESS]; //系统是否有足够的资源 
int p[MAXPROCESS]; //记录序列 
int m,n; //m个进程,n个资源
void Init(){int i,j;printf("-----------银行家算反模拟实现-----------\n");printf("请输入进程的数目m:");scanf("%d",&m);printf("请输入资源的种类n:");scanf("%d",&n);printf("\n");printf("请输入每个进程对资源数的最大需求,按照%d*%d矩阵输入\n",m,n);
//	printf("%d,%d",&m,&n);for(i=0;i<m;i++)   for(j=0;j<n;j++)   scanf("%d",&MAX[i][j]);printf("请输入每个进程已分配的资源数,同样按照%d*%d矩阵输入\n",m,n);for(i=0;i<m;i++){for (j=0;j<n;j++){scanf("%d",&ALLOCATION[i][j]);NEED[i][j]=MAX[i][j]-ALLOCATION[i][j];if(NEED[i][j]<0){printf("进程%d的第%d个资源数超过其最大资源数,请输入\n",i+1,j+1);j--;continue;}}}printf("请输入各个资源现有的数目:\n");for(i=0;i<n;i++)   {   scanf("%d",&AVAILABLE[i]);}   printf("-----------------------------------------------/n");
}bool Safe(){int i,j,k,l=0;int Work[MAXRESOURCE];for(i=0;i<n;i++)   Work[i]=AVAILABLE[i];   for(i=0;i<m;i++)     FINISH[i]=false;//FINISH记录每个进程是否安全    for(i=0;i<m;i++){if(FINISH[i]==true){continue;}else{for(j=0;j<n;j++){if(NEED[i][j]>Work[j]){break;}}if(j==n){FINISH[i]=true;for(k=0;k<n;k++){Work[k]+=ALLOCATION[i][k];//将Work赋值为 第i个进程各个已分配资源数+系统现有的对应资源数(因为当改进程全部资源数都满足时线程结束并将资源返还给系统)   }p[l++]=i;i=-1;}else{continue;}}}if(l==m){printf("the system is safe.\n");printf("the safe list is:\n");for(i=0;i<1;i++){printf("%d",p[i]);if(i!=l-1){printf("-->");}}printf("\n");return true;}else{printf("the system is not safe.\n");return false;}
}
void Bank()
{int i,r;int again;while(1){printf("请输入要申请资源的进程号r:\n");scanf("%d",&r);printf("请输入进程所请求的各资源的数量REQUEST:\n");for(i=0;i<n;i++){   scanf("%d",REQUEST[r][i]);   }   for(i=0;i<n;i++){if(r>m){printf("您输入的请求数超过进程的需求量!请重新输入!\n");break;}if(REQUEST[r][i]>NEED[r][i]&&REQUEST[r][i]>AVAILABLE[i]){printf("您输入的请求数超过系统现有的资源数!请重新输入!\n");break; }}if(i<n) continue;for(i=0;i<n;i++){AVAILABLE[i]-=REQUEST[r][i];//系统可用资源减去申请了的   ALLOCATION[r][i]+=REQUEST[r][i];//线程被分配的资源加上已申请了的   NEED[r][i]-=REQUEST[r][i];//线程还需要的资源减去已申请得到的   }if(Safe()){printf("同意分配请求!\n");}else{printf("您的请求被拒绝!\n");for(i=0;i<n;i++){AVAILABLE[i]+=REQUEST[r][i];   ALLOCATION[r][i]-=REQUEST[r][i];   NEED[r][i]+=REQUEST[r][i];  }}  printf("您还想再次请求资源分配吗?如果是的话请按1,否则请按其他键\n");scanf("%d",&again);if(again==1) continue;break;}
}int main(){Init();Safe();  //检验 Bank();   //资源分配的判断 return 0;
} 

代码中的主要函数和变量包括:

  • Init()函数用于初始化进程数目、资源种类、最大需求矩阵、已分配矩阵和可用资源数组等。
  • Safe()函数用于判断系统是否处于安全状态。它通过遍历进程和资源,检查系统中是否有足够的资源来满足每个进程的需求,如果找到一个安全序列,即进程可以按顺序执行而不发生死锁,就返回true,否则返回false
  • Bank()函数用于进行资源分配判断。它首先接受用户输入的进程号和所请求的资源数量,然后检查请求是否超过进程的需求量和系统现有的资源数。如果请求合法,会尝试分配资源,并调用Safe()函数来判断系统是否仍然处于安全状态。如果安全,即存在安全序列,会打印出同意分配请求的信息;如果不安全,会打印出请求被拒绝的信息,并将资源返还给系统。
  • main()函数是程序的入口,调用Init()进行初始化,然后依次调用Safe()Bank()来进行资源分配判断。

这段代码的目的是模拟银行家算法,判断系统在给定的资源分配情况下是否处于安全状态,以及根据用户的请求来决定是否分配资源。


http://www.ppmy.cn/news/383393.html

相关文章

1、深入掌握TS

环境搭建 npm init -y yarn add typescript -D tsc --init优势 编译时静态类型检测自动提示更清晰明确引入了泛型和一系列的ts特有类型强大的d.ts文件轻松编译成js文件灵活性高 类型注解 let data:number类型推导 let number 30常用的24种ts类型 基本类型 number, stri…

点击el-cascader与tags联动

<el-cascader v-model"queryData.jglx" :options"zclxOption" :props"zclxProps":show-all-levels"false" clearableplaceholder"请选择"ref"jglxRef"change"handleJglxChecked" ></el-cascad…

高端产品销量遥遥领先,九号电动引领行业新风向

2023年3月23日&#xff0c;鲁大师联合艾瑞第二年发布《中国两轮电动车行业白皮书》&#xff0c;对中国电动两轮车行业进行梳理。 在雅迪、爱玛、台铃等几大传统电动两轮车巨头的“层层围剿”下&#xff0c;九号电动以绝对领先的趋势突出重围&#xff0c;整个2022年实现电动两轮…

短出行日渐成熟,电动两轮车迎来下半场

现代化社会中的出行交通方式变得更为便捷&#xff0c;选择也更多元化&#xff0c;在短距离出行这一场景中&#xff0c;人们往往选择更轻量化的交通工具——电动两轮车。 而我国电动两轮车市场从2019年开始实行《电动自行车安全技术规范》所规定的强制性国家标准&#xff0c;这…

中国电子学会2023年05月份青少年软件编程Python等级考试试卷四级真题(含答案)

2023-05 Python四级真题 分数&#xff1a;100 题数&#xff1a;38 测试时长&#xff1a;60min 一、单选题(共25题&#xff0c;共50分) 1. 下列程序段的运行结果是&#xff1f;&#xff08;A&#xff09;&#xff08;2分&#xff09; def s(n):if n0:return 1else:return…

【算法与数据结构】142、LeetCode环形链表 II

文章目录 一、题目二、哈希法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、哈希法 思路分析&#xff1a;这道题也可以用双指针法去解&#xff0c;这里我介绍一种哈希法。利用set集合的值不可重复的特性。…

自动驾驶专题介绍 ———— 激光雷达标定

文章目录 介绍激光雷达与激光雷达之间的外参标定激光雷达与摄像头的标定 介绍 激光雷达在感知、定位方面发挥着重要作用。跟摄像头一样&#xff0c;激光雷达也是需要进行内外参数标定的。内参标定是指内部激光发射器坐标系与雷达自身坐标系的转换关系&#xff0c;在出厂之前就已…

红帽认证常见答疑(二):电脑配置、实验环境和考试环境、可以自学吗

学习红帽需要配置什么样的电脑&#xff1f; RHCE推荐学员自己的电脑内存在16G左右&#xff0c;RHCA推荐学员电脑内存在32-64G&#xff0c;且最好配置128G以上的固态硬盘&#xff0c;如果自己没有该配置的电脑&#xff0c;誉天可以提供远程学习环境&#xff0c;可以随时随地连接…