实验四 银行家算法模拟
- 格式:doc
- 大小:59.00 KB
- 文档页数:7
实验四银行家算法的实现1、实验目的通过编写和调试银行家算法的模拟程序以加深对避免死锁方案的理解。
熟悉银行家算法的分配思想。
2、实验要求设计一个银行家方案。
并编写模拟程序实现之。
已知系统总共的资源数、进程名、进程已分配的资源、进程运行完毕最大最资源的需求量,以书上例题为例,分析某一时刻系统是否会产生死锁。
3、算法描述银行家算法中数据结构如下:n :系统中的进程个数;m :系统中的资源类数。
1)Available(m):现有资源向量。
Available(j)=k表示k个未分配的j类资源2)Max(n,m):资源最大申请量矩阵。
Max(i,j)=k表示第i个进程在运行过程中对第j类资源的最大申请量为k。
3)Allocation(n,m):资源分配矩阵。
Allocation(i,j)=k表示进程i已占有k个j类资源。
4)Need(n,m):进程以后还需要的资源矩阵。
Need(i,j)=k表示进程i以后还需要k个第j类资源。
显然有Need[i,j]=Max[i,j]-Allocation[i,j]。
5)Request(n,m):进程申请资源矩阵。
Request(i,j)=k表示进程i申请k个第j类资源。
银行家算法思想如下:若进程i申请资源,申请资源向量为Request(i),则有如下资源分配过程:1)如果Request(i)〉Need(i),则报错返回。
2)如果Request(i)〉Avaliable,则进程i进入等待资源状态,返回。
3)假设进程进程i的申请已获批准,于是修改系统状态:Avaliable=Avaliable-Request(i)Allocation(i)=Allocation(i)+Request(i)Need(i)=Need(i)-Request(i)4)调用安全状态检查算法。
设Work(m)为临时工作向量。
初始时Work=Available。
令N={1,2,……n}。
寻求j∈N 使其满足:Need(j)<=Work,若不存在这样的j则转至3)。
项目四银行家算法模拟1.设计原理银行家算法基本原理:操作系统在每一次分配之前都要进行以下操作,判断当前的资源请求是否安全,如果安全则实施分配,否则不予分配。
第1步:操作系统对提出资源请求的进程按所请求的资源数目实施预分配,修改剩余资源数组、资源分配矩阵和剩余资源请求矩阵;第2步:将剩余资源数组代入剩余需求矩阵中与各元素进行比较,找到可以满足其所有资源需求的某个进程将它加入到安全序列中;第3步:将该进程运行结束后释放的资源累加到剩余资源数组中;第4步:再重复第2、3两步。
若所有进程都能够进入安全序列<Pi,Pj,……>,则此次分配可以实施,否则系统将会处于不安全状态,因而不能实施分配。
如果不能实施分配,则将系统还原到预分配之前的状态。
2.设计步骤和方法(1)设计数据结构:剩余资源数组available,如available[j] = k 表示资源Rj现有k个。
(2)设计数据结构:最大资源请求矩阵max,如max [i][j] = k表示进程Pi最多可申请k个类型为Rj的资源。
(3)设计数据结构:资源分配矩阵allocation,定义每个进程现在所分配的各种资源类型的数量,如allocation [i][j] = k表示进程Pi现在分配了k个类型为Rj的资源。
(4)设计数据结构:剩余资源请求矩阵claim,定义每个进程还需要的剩余的资源数,如claim [i][j] = k表示进程Pi还需要申请k个类型Rj的资源。
其中,claim [i][j] = max[i][j] -allocation[i][j]。
(5)设计函数完成功能:系统内资源总数已知、各进程对各类资源最大需求数目已知、已分配资源数目已知的前提下,某进程提出各类资源的需求量时能判断状态是否安全,以决定是否予以分配。
银行家算法的模拟实现实验报告银行家算法的模拟实现一、实验题目:模拟实现银行家算法的处理过程二、实验目的:银行家算法是避免死锁的代表性算法。
本实习旨在加深了解有关资源申请、避免死锁、状态安全性等概念,并体会和运用避免死锁的具体实施方法。
然后依照本实习,自行设计模拟程序。
三、实验原理:1.我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
操作系统按照银行家制定的规则为进程分配资源。
当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。
当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过了该进程对资源的最大需求量。
若超过则拒绝分配资源,若没有超过则再测试系统现存的资源能否满足该进程尚需的最大资源量,若能满足则按当前的申请量分配资源,否则也要推迟分配。
2. 安全状态:如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。
安全状态一定是没有死锁发生。
不安全状态:不存在一个安全序列。
不安全状态一定导致死锁。
安全序列:一个进程序列{P1,…,Pn}是安全的,如果对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj (j < i )当前占有资源量之和。
3. 设requesti为进程p[i]的请求向量,如果requesti[j]=K,表示进程p[i]需要K个Rj资源。
当系统发出请求后,系统按下述步骤开始检查:1)如果requesti[j]<=need[i][j],转向步骤2;否则报告出错,申请的资源已经大于它需要的最大值。
2)如果requesti[j]<=available[j],转向步骤3;否则报告出错,尚无足够的资源。
3)系统试探着把资源分配给p[i],并修改下列数据结构中的值:available[j]=available[j]-request[j]allocation[i][j]=allocation[i][j]+request[j]need[i][j]=need[i][j]-request[j]4)系统进行安全性算法,检查此次分配后,系统是否还处于安全状态,若安全,把资源分配给进程p[i];否则,恢复原来的资源分配状态,让进程p[i]等待。
《银行家算法的模拟实现》 --实验报告题目: 银行家算法的模拟实现专业:班级:组员:指导老师:一、实验目的死锁会引起计算机工作僵死,因此操作系统中必须防止。
本实验的目的在于让学生独立的使用高级语言编写和调试一个系统动态分配资源的简单模拟程序,了解死锁产生的条件和原因,并采用银行家算法有效地防止死锁的发生,以加深对课堂上所讲授的知识的理解。
二、实验内容模拟实现银行家算法实现死锁避免。
要求:初始数据(如系统在T0时刻的资源分配情况、每一种资源的总数量)从文本文件读入,文件中给出最大需求矩阵Max、分配矩阵Allocation,在程序中求得需求矩阵Need和可利用资源向量Available。
三、实验分析过程1、整个银行家算法的思路。
先对用户提出的请求进行合法性检查,再进行预分配,利用安全性检查算法进行安全性检查。
1)进程一开始向系统提出最大需求量.2)进程每次提出新的需求(分期贷款)都统计是否超出它事先提出的最大需求量.3)若正常,则判断该进程所需剩余剩余量(包括本次申请)是否超出系统所掌握的剩余资源量,若不超出,则分配,否则等待2、算法用到的主要数据结构和C语言说明。
(1)、可利用资源向量INT A V AILABLE[M] M为资源的类型。
(2)、最大需求矩阵INT MAX[N][M] N为进程的数量。
(3)、已分配矩阵INT ALLOCA TION[N][M](4)、还需求矩阵INT NEED[N][N](5)、申请各类资源数量int Request[x]; //(6)、工作向量int Work[x];(7)、int Finish[y]; //表示系统是否有足够的资源分配给进程,0为否,非0为是3、银行家算法(主程序)(1)、系统初始化。
输入进程数量,资源种类,各进程已分配、还需求各资源数量,各资源可用数量等(2)、输入用户的请求三元组(I,J,K),为进程I申请K个J类资源。
(3)、检查用户的请求是否小于还需求的数量,条件是K<=NEED[I,J]。
模拟银行家算法模拟银行家算法课程设计任务书设计题目:编程序模拟银行家算法设计目的1、银行家算法是避免死锁的一种重要方法,本实验要求用高级语言编写和调试一个简单的银行家算法程序。
加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。
2、提高学生的程序设计能力、提高算法设计质量与程序设计素质 ;设计任务 (在规定的时间内完成下列任务)思想:将一定数量的资金供多个用户周转使用,当用户对资金的最大申请量不超过现存资金时可接纳一个新客户,客户可以分期借款,但借款总数不能超过最大的申请量。
银行家对客户的借款可以推迟支付,但是能够使客户在有限的时间内得到借款,客户得到所有的借款后能在有限的时间内归还。
用银行家算法分配资源时,测试进程对资源的最大需求量,若现存资源能满足最大需求就满足当前进程的申请,否则推迟分配,这样能够保证至少有一个进程可以得到所需的全部资源而执行到结束,然后归还资源,若OS能保证所有进程在有限的时间内得到所需资源则称系统处于安全状态。
1. 需求分析1.1 课程设计题目编程序模拟银行家算法1.2 课程设计目的`1、银行家算法是避免死锁的一种重要方法,本实验要求用高级语言编写和调试一个简单的银行家算法程序。
加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。
2、提高自己的程序设计能力、提高算法设计质量与程序设计素质;1.3 课程设计任务及要求思想:将一定数量的资金供多个用户周转使用,当用户对资金的最大申请量不超过现存资金时可接纳一个新客户,客户可以分期借款,但借款总数不能超过最大的申请量。
银行家对客户的借款可以推迟支付,但是能够使客户在有限的时间内得到借款,客户得到所有的借款后能在有限的时间内归还。
银行家算法在系统在分配资源时自始自终地做出正确的选择,这样可以避免死锁的发生。
用银行家算法分配资源时,测试进程对资源的最大需求量,若现存资源能满足最大需求就满足当前进程的申请,否则推迟分配,这样能够保证至少有一个进程可以得到所需的全部资源而执行到结束,然后归还资源,若OS能保证所有进程在有限的时间内得到所需资源则称系统处于安全状态。
操作系统实验实验四银行家算法学号 1115102002姓名蔡凤武班级 11电子A华侨大学电子工程系实验目的1、理解银行家算法。
2、掌握进程安全性检查的方法与资源分配的方法。
实验内容与基本要求编制模拟银行家算法的程序,并以下面给出的例子验证所编写的程序的正确性。
现在系统中A、B、C、D 4类资源分别还剩1、5、2、0个,请按银行家算法回答:1、现在系统是否处于安全状态?2、如果现在进程P1提出需要(0、4、2、0)个资源的请求,系统能否满足它的请求?1、银行家算法和安全性检查算法原理。
操作系统的银行家算法:当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。
当进程在执行中继续申请资源时,先测试该进程本次申请的资源数是否超过了该资源所剩余的总量。
若超过则拒绝分配资源,若能满足则按当前的申请量分配资源,否则也要推迟分配。
1、程序流程描述。
银行家算法:(1) 步骤:1如果Request [j]<=Need[i],转向步骤(2),否则认为出错,因为他所需要的资源数已经超过它所宣布的最大值。
(2) 步骤2;如果:Request [i]<=Available[i],转向步骤(3),否则提示尚无足够资源,进程i需等待。
(3) 步骤3:系统试探分配相关资源,并修改下面数据:Available[i]= Available[i]- Request [j];Allocation[i]= Allocat ion[i]+ Request [i];Need[i]= Need[i]- Request [i];(4) 步骤4:执行安全性检查,如安全,则分配成立;否则本次试探分配作废,恢复原来的资源分配状态,让该进程等待。
安全性检查算法:安全性检查算法主要是根据银行家算法进行资源分配后,检查资源分配后的系统状态之中。
具体算法如下:(1) 步骤1:设置两个向量: Work= Available,Finish[i]=false;说明:Finish(它表示系统是否有足够的资源分配给进程)Work(它表示系统可提供给进程继续运行所需的各类资源数目)(2) 步骤2:在进程中查找符合以下条件的进程:Finish[i]=false,need<=Work 若能找到,则执行步骤(3),否则,执行步骤(4)(3) 步骤3:当进程获得资源后,可顺利执行,直至完成,从而释放资源:Work= Work+ Allocation; Finish=true; goto step (2);(4) 步骤4:如果所有进程的Finish=true都满足,则表示系统处于安全状态,否则,系统不安全状态。
武汉理工大学华夏学院课程设计报告书课程名称:操作系统原理题目:编程序模拟银行家算法系名:信息工程系专业班级:计应2091姓名:王汝平学号: 10225509118 指导教师:苏永红2011 年 7 月 6 日课程设计任务书学生姓名:王汝平专业班级:计应2091指导教师:苏永红工作单位:信息工程系设计题目:编程序模拟银行家算法初始条件:Linux操作系统,GCC编译环境要求完成的主要任务:主要任务:银行家算法是避免死锁的一种重要方法,本实验要求用高级语言编写和调试一个简单的银行家算法程序。
加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。
思想:将一定数量的资金供多个用户周转使用,当用户对资金的最大申请量不超过现存资金时可接纳一个新客户,客户可以分期借款,但借款总数不能超过最大的申请量。
银行家对客户的借款可以推迟支付,但是能够使客户在有限的时间内得到借款,客户得到所有的借款后能在有限的时间内归还。
用银行家算法分配资源时,测试进程对资源的最大需求量,若现存资源能满足最大需求就满足当前进程的申请,否则推迟分配,这样能够保证至少有一个进程可以得到所需的全部资源而执行到结束,然后归还资源,若OS能保证所有进程在有限的时间内得到所需资源则称系统处于安全状态。
设计报告撰写格式要求:1设计题目与要求 2 设计思想3系统结构 4 数据结构的说明和模块的算法流程图5 使用说明书(即用户手册):内容包含如何登录、退出、读、写等操作说明6 运行结果和结果分析(其中包括实验的检查结果、程序的运行情况)7 自我评价与总结 8 附录:程序清单,注意加注释(包括关键字、方法、变量等),在每个模块前加注释;时间安排7月 4日布置课程设计任务;分配题目后,查阅资料、准备程序;7月 5 ~7月7 日上机调试程序、书写课程设计报告;7月8 日提交课程设计报告及相关文档。
指导教师签名:2011年7月2日系主任签名:2011年7月3日目录1.需求分析 (4)1.1课程设计题目 (4)1.2课程设计目的 (4)1.3设计任务 (4)1.4设计思想 (4)2.设计思想和过程 (5)2.1 概要设计 (5)2.2程序源代码 (7)3.调试及运行结果 (13)4.实验心得体会 (15)5.参考文献 (15)1.需求分析1.1课程设计题目:编程序模拟银行家算法1.2设计目的1.2.1银行家算法是避免死锁的一种重要方法,本实验要求用级语言编写和调试一个简单的银行家算法程序。
武汉轻工大学数学与计算机学院《操作系统》实验报告题目:模拟实现银行家算法专业:数学与计算机学院班级:计算机类1303班学号: 1305110050 姓名:刘文斌指导老师:黄川2015年05月26日1、目的和要求在熟练掌握死锁发生原理和解决死锁问题的基础上,利用一种程序设计语言模拟实现利用银行家算法实现死锁避免,一方面加深对原理的理解,另一方面提高学生通过编程根据已有原理解决实际问题的能力,为学生将来进行系统软件开发和针对实际问题提出高效的软件解决方案打下基础。
2、实验内容模拟实现银行家算法对系统资源进行分配,以防止死锁的出现。
本课题肯定不可能实现对实际操作系统的资源管理,而是通过对模拟资源数据的处理,检测银行家算法在防止死锁出现的作用。
银行家算法描述:第一部分:银行家算法(扫描)1.如果Request<=Need,则转向2;否则,出错2.如果Request<=Available,则转向3,否则等待3.系统试探分配请求的资源给进程4.系统执行安全性算法第二部分:安全性算法1.设置两个向量(1).工作向量:Work=Available(表示系统可提供给进程继续运行所需要的各类资源数目)(2).Finish:表示系统是否有足够资源分配给进程(True:有;False:没有).初始化为False2.若Finish[i]=False&&Need<=Work,则执行3;否则执行4(i为资源类别)3.进程P获得第i类资源,则顺利执行直至完成,并释放资源:Work=Work+Allocation;Finish[i]=true;3、实验环境Windows操作系统、VC++6.0C语言4、设计思想当进程pi提出资源申请时,系统执行下列步骤:(1)若Request[i]≤Need[i],转(2);否则错误返回(2)若Request[i]≤Available,转(3);否则进程等待(3)假设系统分配了资源,则有:Available:=Available-Request[i];Allocation[i]:=Allocation[i]+Request[i];Need[i]:=Need[i]-Request[i]若系统新状态是安全的,则分配完成若系统新状态是不安全的,则恢复原状态,进程等待模拟实现Dijkstra的银行家算法以避免死锁的出现.分两部分组成:5、源程序#include <iostream>using namespace std;#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();bool Safe();void Bank();int main(){Init();Safe();Bank();}void Init() /*初始化算法*/{int i,j;cout<<"\t---------------------------------------------------"<<endl; cout<<"\t||||"<<endl;cout<<"\t|| 银行家算法||"<<endl;cout<<"\t||||"<<endl;cout<<"\t|| XXXXXXXXXXXXXXXXXXXX ||"<<endl;cout<<"\t||||"<<endl;cout<<"\t|| 2004024031 2004024054||"<<endl;cout<<"\t---------------------------------------------------"<<endl;cout<<"请输入进程的数目:";cin>>m;cout<<"请输入资源的种类:";cin>>n;cout<<"请输入每个进程最多所需的各资源数,按照"<<m<<"x"<<n<<"矩阵输入"<<endl;for(i=0;i<m;i++)for(j=0;j<n;j++)cin>>MAX[i][j];cout<<"请输入每个进程已分配的各资源数,也按照"<<m<<"x"<<n<<"矩阵输入"<<endl;for(i=0;i<m;i++){for(j=0;j<n;j++){cin>>ALLOCATION[i][j];NEED[i][j]=MAX[i][j]-ALLOCATION[i][j];if(NEED[i][j]<0){cout<<"您输入的第"<<i+1<<"个进程所拥有的第"<<j+1<<"个资源数错误,请重新输入:"<<endl;j--;continue;}}}cout<<"请输入各个资源现有的数目:"<<endl;for(i=0;i<n;i++){cin>>AVAILABLE[i];}}void Bank() /*银行家算法*/{int i,cusneed;char again;while(1){cout<<"请输入要申请资源的进程号(注:第1个进程号为0,依次类推)"<<endl;cin>>cusneed;cout<<"请输入进程所请求的各资源的数量"<<endl;for(i=0;i<n;i++){cin>>REQUEST[cusneed][i];}for(i=0;i<n;i++){if(REQUEST[cusneed][i]>NEED[cusneed][i]){cout<<"您输入的请求数超过进程的需求量!请重新输入!"<<endl;continue;}if(REQUEST[cusneed][i]>AVAILABLE[i]){cout<<"您输入的请求数超过系统有的资源数!请重新输入!"<<endl;continue;}}for(i=0;i<n;i++){AVAILABLE[i]-=REQUEST[cusneed][i];ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];NEED[cusneed][i]-=REQUEST[cusneed][i];}if(Safe()){cout<<"同意分配请求!"<<endl;}else{cout<<"您的请求被拒绝!"<<endl;for(i=0;i<n;i++){AVAILABLE[i]+=REQUEST[cusneed][i];ALLOCATION[cusneed][i]-=REQUEST[cusneed][i];NEED[cusneed][i]+=REQUEST[cusneed][i];}}for(i=0;i<m;i++){FINISH[i]=false;}cout<<"您还想再次请求分配吗?是请按y/Y,否请按其它键"<<endl; cin>>again;if(again=='y'||again=='Y'){continue;}break;}}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;}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]; }p[l++]=i;i=-1;}else{ continue;}}if(l==m){cout<<"系统是安全的"<<endl;cout<<"安全序列:"<<endl;for(i=0;i<l;i++){cout<<p[i];if(i!=l-1){cout<<"-->";}}cout<<""<<endl;return true;}}cout<<"系统是不安全的"<<endl;return false;}6、实例运行结果7、总结操作系统的基本特征是并发与共享。
实验四、银行家算法(一)目的和要求银行家算法是由Dijkstra设计的最具有代表性的避免死锁的算法。
本实验要求用高级语言编写一个银行家的模拟算法。
通过本实验可以对预防死锁和银行家算法有更深刻的认识。
(二)实验内容1、设置数据结构包括可利用资源向量(Availiable),最大需求矩阵(Max),分配矩阵(Allocation),需求矩阵(Need)2、设计安全性算法设置工作向量Work 表示系统可提供进程继续运行可利用资源数目,Finish 表示系统是否有足够的资源分配给进程(三)实验环境1、pc2、vc++(四)、程序源代码:/*子函数声明*/int Isprocessallover(); //判断系统中的进程是否全部运行完毕void Systemstatus(); //显示当前系统中的资源及进程情况int Banker(int ,int *); //银行家算法void Allow(int ,int *); //若进程申请不导致死锁,用此函数分配资源void Forbidenseason(int ); //若发生死锁,则显示原因/*全局变量*/int Availiable[3]={3,3,2}; //初始状态,系统可用资源量int Max[5][3]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};//各进程对各资源的最大需求量int Allocation[5][3]={{0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2}};//初始状态,各进程占有资源量int Need[5][3]={{7,4,3},{1,2,2},{6,0,0},{0,1,1},{4,3,1}};//初始状态时,各进程运行完毕,还需要的资源量int over[5]={0,0,0,0,0}; //标记对应进程是否得到所有资源并运行完毕#include <iostream.h>/*主函数*/void main(){int process=0; //发出请求的进程int decide=0; //银行家算法的返回值int Request[3]={0,0,0}; //申请的资源量数组int sourcenum=0; //申请的各资源量/*判断系统中进程是否全部运行完毕*/step1: if(Isprocessallover()==1){cout<<"系统中全部进程运行完毕!";return;}/*显示系统当前状态*/Systemstatus();/*人机交互界面*/step2: cout<<"\n输入发出请求的进程(输入“0”退出系统): ";cin>>process;if(process==0){cout<<"放弃申请,退出系统!";return;}if(process<1||process>5||over[process-1]==1){cout<<"系统无此进程!\n";goto step2;}cout<<"此进程申请各资源(A,B,C)数目:\n";for(int h=0;h<3;h++){cout<<char(65+h)<<"资源:";cin>>sourcenum;Request[h]=sourcenum;}/*用银行家算法判断是否能够进行分配*/decide=Banker(process,Request);if (decide==0){/*将此进程申请资源分配给它*/Allow(process,Request);goto step1;}else{/*不能分配,显示原因*/Forbidenseason(decide);goto step2;}}/*子函数Isprocessallover( )的实现*/int Isprocessallover(){int processnum=0;for(int i=0;i<5;i++){/*判断每个进程是否运行完毕*/if(over[i]==1)processnum++;}if(processnum==5)/*系统中全部进程运行完毕*/return 1;elsereturn 0;}/*子函数Systemstatus( )的实现*/void Systemstatus(){cout<<"此刻系统中存在的进程:\n";for(int i=0;i<5;i++){if(over[i]!=1)cout<<"P"<<i+1<<" ";}cout<<endl;cout<<"此刻系统可利用资源(单位:个):\n";cout<<"A B C\n";for(int a=0;a<3;a++){cout<<Availiable[a]<<" ";}cout<<endl;cout<<"此刻各进程已占有资源如下(单位:个): \n"<<" A B C\n";for(int b=0;b<5;b++){if(over[b]==1)continue;cout<<"P"<<b+1<<" ";for(int c=0;c<3;c++)cout<<Allocation[b][c]<<" ";cout<<endl;}cout<<"各进程运行完毕还需各资源如下(单位:个):\n"<<" A B C\n";for(int f=0;f<5;f++){if(over[f]==1)continue;cout<<"P"<<f+1<<" ";for(int g=0;g<3;g++)cout<<Need[f][g]<<" ";cout<<endl;}}/*子函数Banker(int ,int &)的实现*/int Banker(int p,int *R){int num=0; //标记各资源是否能满足各进程需要int Finish[5]={0,0,0,0,0}; //标记各进程是否安全运行完毕int work[5]={0,0,0,0,0}; //用于安全检查int AvailiableTest[3]; //用于试分配int AllocationTest[5][3]; //同上int NeedTest[5][3]; //同上/*判断申请的资源是否大于系统可提供的资源总量*/for(int j=0;j<3;j++){if(*(R+j)>Availiable[j])/*返回拒绝分配原因*/return 1;}/*判断该进程申请资源量是否大于初始时其申明的需求量*/for(int i=0;i<3;i++){if(*(R+i)>Need[p-1][i])/*返回拒绝原因*/return 2;}/*为检查分配的各数据结构赋初值*/for(int t=0;t<3;t++){AvailiableTest[t]=Availiable[t];}for(int u=0;u<5;u++){for(int v=0;v<3;v++){AllocationTest[u][v]=Allocation[u][v];}}for(int w=0;w<5;w++){for(int x=0;x<3;x++){NeedTest[w][x]=Need[w][x];}}/*进行试分配*/for(int k=0;k<3;k++)//修改NeedTest[]{AvailiableTest[k]-=*(R+k);AllocationTest[p-1][k]+=*(R+k);NeedTest[p-1][k]-=*(R+k);}/*检测进程申请得到满足后,系统是否处于安全状态*/ for(int l=0;l<3;l++){work[l]=AvailiableTest[l];}for(int m=1;m<=5;m++){for(int n=0;n<5;n++){num=0;/*寻找用此刻系统中没有运行完的进程*/if(Finish[n]==0&&over[n]!=1){for(int p=0;p<3;p++){if(NeedTest[n][p]<=work[p])num++;}if(num==3){for(int q=0;q<3;q++){work[q]=work[q]+AllocationTest[n][q];}Finish[n]=1;}}}}for(int r=0;r<5;r++){if(Finish[r]==0&&over[r]!=1)/*返回拒绝分配原因*/return 3;}return 0;}/*子函数Allow(int ,int &)的实现*/void Allow(int p,int *R){cout<<"可以满足申请!";static int overnum;/*对进程所需的资源进行分配*/for(int t=0;t<3;t++){Availiable[t]=Availiable[t]-*(R+t);Allocation[p-1][t]=Allocation[p-1][t]+*(R+t);Need[p-1][t]=Need[p-1][t]-*(R+t);}/*分配后判断其是否运行完毕*/overnum=0;for(int v=0;v<3;v++){if(Need[p-1][v]==0)overnum++;}if(overnum==3){/*此进程运行完毕,释放其占有的全部资源*/for(int q=0;q<3;q++)Availiable[q]=Availiable[q]+Allocation[p-1][q];/*标记该进程运行完毕*/over[p-1]=1;cout<<"进程P"<<p<<"所需资源全部满足,此进程运行完毕!\n";}}/*子函数Forbidenseason(int )的实现*/void Forbidenseason(int d){cout<<"不能满足申请,此进程挂起,原因为:\n";switch (d){case 1:cout<<"申请的资源量大于系统可提供的资源量!";break;case 2:cout<<"申请的资源中有某种资源大于其声明的需求量!";break;case 3:cout<<"若满足申请,系统将进入不安全状态,可能导致死锁!";}}。
实验四银行家算法模拟
【实验目的】
(1)进一步理解利用银行家算法避免死锁的问题;
(2)在了解和掌握银行家算法的基础上,编制银行家算法通用程序,将调试结果显示在计算机屏幕上,再检测和笔算的一致性。
(3)理解和掌握安全序列、安全性算法
【实验要求】
(1)了解和理解死锁;
(2)理解利用银行家算法避免死锁的原理;
(3)会使用某种编程语言。
【实验原理】
一、安全状态
指系统能按照某种顺序如<P1,P2,…,Pn>(称为<P1,P2,…,Pn>序列为安全序列),为每个进程分配所需的资源,直至最大需求,使得每个进程都能顺利完成。
二、银行家算法
假设在进程并发执行时进程i提出请求j类资源k个后,表示为Requesti[j]=k。
系统按下述步骤进行安全检查:
(1)如果Requesti≤Needi则继续以下检查,否则显示需求申请超出最大需求值的错误。
(2)如果Requesti≤Available则继续以下检查,否则显示系统无足够资源,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];
(4)系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。
若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。
三、安全性算法
(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都满足,则表示系统处于安全状态;否则,系统处于不安全状态。
【实验步骤】
参考实验步骤如下:
(1)参考图1-1所示流程图编写安全性算法。
(2
每次提出申请之后输出申请成功与否的结果。
如果成功还需要输出变化前后的各种数据,并且输出安全序列。
(3)参考图1-2所示流程图编写银行家算法。
(4)编写主函数来循环调用银行家算法。
【实验示例】
#include <stdio.h>
int main()
{
int claim[5][3]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};//各线程最大需求量
int allocation[5][3]={{0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2}};//各线程已分配资源int i,j,k,l=0,count=0,m=0;
int C_A[5][3]={{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};//各进程仍需要的各类资源int result[5]={-1,-1,-1,-1,-1};//存放预分配成功的线程
int currentavail[3]={3,3,2};//当前可分配资源
printf("银行家总共拥有的各类资源的总数:\n A B C\n 10 5 7\n");
printf("银行目前仍剩下的各类资源的数量:\n A B C\n 3 3 2\n");
printf("各进程对各类资源的最大需求量:\n A B C\n");
for(i=0;i<5;i++)
{
printf("P%d: ",i);
for(j=0;j<3;j++)
{
printf(" %d ",claim[i][j]);
C_A[i][j]=claim[i][j]-allocation[i][j];
}
printf("\n");
}
printf("各进程已分配到的各类资源:\n A B C\n");
for(i=0;i<5;i++)
{
printf("P%d: ",i);
for(j=0;j<3;j++)
printf(" %d ",allocation[i][j]);
printf("\n");
}
printf("各进程仍需的各类资源数量:\n A B C\n");
for(i=0;i<5;i++)
{
printf("P%d: ",i);
for(j=0;j<3;j++)
printf(" %d ",C_A[i][j]);
printf("\n");
}
while(result[l]==-1)//
{
for(k=0;k<5;k++)
if(result[k]==-1)
{
for(j=0;j<3;j++)
//判断各线程对各资源仍需量是否小于当前可分配资源总量,此量为正数才正常
if(C_A[k][j]<=currentavail[j]&&C_A[k][j]>=0)
{
//把满足条件的进程的已分配资源加到当前可分配资源中
currentavail[j]=currentavail[j]+allocation[k][j];
m++;
if(m==3)
{
result[l]=k;//只有ABC三类资源都满足才把相应的线程记入数组result中
m=0;
}
}
else break;//否则退出循环,打印"系统不安全"
l++;
for(i=0;i<l;i++)
if(result[i]!=-1)
{
printf("P%d->",result[i]);//把预分配成功的先打印出来
count++;
}
l=0;//清零,为下一轮的预分配做准备
}
if(count==5)
printf("\n系统安全!上行所示为其中一个进程安全序列\n");
else
printf("\n系统不安全!\n");
}
结果如下:
银行家总共拥有的各类资源的总数:
A B C
10 5 7
银行目前仍剩下的各类资源的数量:
A B C
3 3 2
各进程对各类资源的最大需求量:
A B C
P0: 7 5 3
P1: 3 2 2
P2: 9 0 2
P3: 2 2 2
P4: 4 3 3
各进程已分配到的各类资源:
A B C
P1: 2 0 0
P2: 3 0 2
P3: 2 1 1
P4: 0 0 2
各进程仍需的各类资源数量:
A B C
P0: 7 4 3
P1: 1 2 2
P2: 6 0 0
P3: 0 1 1
P4: 4 3 1
P1->P3->P4->P0->P2->
系统安全!上行所示为其中一个进程安全序列
【思考题】
(1)在编程中遇到了哪些问题?你是如何解决的?
(2)在安全性算法中,为什么不用变量Available,而又定义一个临时变量work?。