1、操作系统课程设计(银行家算法的模拟实现)1、设计目的1、进一步了解进程的并发执行。2、加强对进程死锁的理解。3、用银行家算法完成死锁检测。2、设计内容给出进程需求矩阵C、资源向量R以及一个进程的申请序列。使用进程启动拒绝和资源分配拒绝(银行家算法)模拟该进程组的执行情况。3、设计要求1、初始状态没有进程启动。2、计算每次进程申请是否分配,如:计算出预分配后的状态情况(安全状态、不安全状态),如果是安全状态,输出安全序列。3、每次进程申请被允许后,输出资源分配矩阵A和可用资源向量V。4、每次申请情况应可单步查看,如:输入一个空格,继续下个申请。4、算法原理1、银行家算法中
2、的数据结构(1)、可利用资源向量Available,这是一个含有m个元素的数组,其中的每个元素代表一类可利用资源的数目,其初始值是系统中所配置的该类全部资源的数目,其数值随该类资源的分配和回收而动态改变。如果Availablej=K,则表示系统中现有Rj类资源K个。(2)、最大需求矩阵Max,这是一个n*m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Maxi,j=K,则表示进程i需要Rj类资源的最大数目为K。(3)、分配矩阵Allocation。这也是一个n*m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocationi,j=K,则表示进
3、程i当前已经分得Rj类资源的数目为K。(4)、需求矩阵Need。这也是一个n*m的矩阵,用以表示每个进程尚需要的各类资源数。如果Needi,j=K,则表示进程i还需要Rj类资源K个,方能完成其任务。上述三个矩阵间存在以下关系:Needi,j=Maxi,j-Allocationi,j2、银行家算法应用模拟实现Dijkstra的银行家算法以避免死锁的出现,分两部分组成:一是银行家算法(扫描);二是安全性算法。(1)银行家算法(扫描)设Requesti是进程Pi的请求向量,如果Requestij=K,表示进程Pi需要K个Ri类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:如果Req
4、uestij=Needi,j,便转向步骤;否则认为出错,因为它所需的资源数已经超过了它所宣布的最大值。如果Requestij=Allocationi,j,便转向步骤;否则表示尚无足够资源,Pi需等待。系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值。Availablej=Available-Requestij;Allocationi,j=Allocationi,j+Requestij;Needi,j=Needi,j-Requestij;系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,已完成本次分配;否则,将本次的试探分配作
5、废,恢复原来资源的分配状态,让进程Pi等待。(2)安全性算法系统所执行的安全性算法可描述如下:设置两个向量:一个是工作向量Work;它表示系统可提供给进程继续运行所需要的各类资源的数目,它含有m个元素,在执行安全性算法开始时,work=Available;另一个是Finish;它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finishi=false;当有足够资源分配给进程时,再令Finishi=true;从进程集合中找到能满足下述条件的进程:一是Finishi=false;二是Needi,j=Workj;若找到,执行步骤,否则,执行步骤;当进程Pi获得资源后,可顺利
6、执行,直至完成,并释放出分配给它的资源,故应执行:Workj=Workj+Allocationi,j;Finishi=true;gotostep;如果所有进程的Finishi=true都满足,则表示系统处于安全状态,否则系统处于不安全状态。5、设计思路1、进程一开始向系统提出最大需求量;2、进程每次提出新的需求(分期贷款)都统计是否超出它事先提出的最大需求量;3、若正常,则判断该进程所需剩余量(包括本次申请)是否超出系统所掌握的剩余资源量,若不超出,则分配,否则等待。六、程序运行调试结果1、程序初始化2、检测系统资源分配是否安全结果7、小结“银行家算法的模拟实现”
8、试过程中我遇到了许多的问题,通过网上查询资料、翻阅课本、向同学请教、多次调试等方法逐渐解决了大部分问题。让我收获很多,相信在今后的生活中也有一定帮助。附:程序源代码:#include#include#include#definem50intno1;/进程数intno2;/资源数intr;intallocationmm,needmm,availablem,maxmm;charname1m,name2m;/定义全局变量voidmain()voidcheck();voidprint();inti,j,p=0,q=0;charc;intrequestm,al
9、location1mm,need1mm,available1m;printf(*n);printf(*银行家算法的设计与实现*n);printf(*n);printf(请输入进程总数:n);scanf(%d,&no1);printf(请输入资源种类数:n);scanf(%d,&no2);printf(请输入Max矩阵:n);for(i=0;ino1;i+)for(j=0;jno2;j+)scanf(%d,&maxij);/输入已知进程最大资源需求量printf(请输入Allocation矩阵:n);for(i=0;ino1;i+)for(j=0;jno2;j+)scanf(%d,&a
10、llocationij);/输入已知的进程已分配的资源数for(i=0;ino1;i+)for(j=0;jno2;j+)needij=maxij-allocationij;/根据输入的两个数组计算出need矩阵的值printf(请输入Available矩阵n);for(i=0;ino2;i+)scanf(%d,&availablei);/输入已知的可用资源数print();/输出已知条件check();/检测T0时刻已知条件的安全状态if(r=1)/如果安全则执行以下代码doq=0;p=0;printf(n请输入请求资源的进程号(04):n);for(j=0;j=no1)p
11、rintf(输入错误,请重新输入:n);continue;elsebreak;printf(n请输入该进程所请求的资源数requestj:n);for(j=0;jno2;j+)scanf(%d,&requestj);for(j=0;jneedij)p=1;/判断请求是否超过该进程所需要的资源数if(p)printf(请求资源超过该进程资源需求量,请求失败!n);elsefor(j=0;javailablej)q=1;/判断请求是否超过可用资源数if(q)printf(没有做够的资源分配,请求失败!n);else/请求满足条件for(j=0;jno2;j+)available
12、1j=availablej;allocation1ij=allocationij;need1ij=needij;/保存原已分配的资源数,仍需要的资源数和可用的资源数availablej=availablej-requestj;allocationij+=requestj;needij=needij-requestj;/系统尝试把资源分配给请求的进程print();check();/检测分配后的安全性if(r=0)/如果分配后系统不安全for(j=0;jno2;j+)availablej=available1j;allocationij=allocation1ij;needij=
13、need1ij;/还原已分配的资源数,仍需要的资源数和可用的资源数printf(返回分配前资源数n);print();printf(n你还要继续分配吗?YorNn);/判断是否继续进行资源分配c=getche();while(c=y|c=Y);voidcheck()/安全算法函数intk,f,v=0,i,j;intworkm,am;boolfinishm;r=1;for(i=0;ino1;i+)finishi=false;/初始化进程均没得到足够资源数并完成for(i=0;ino2;i+)worki=availablei;/worki表示可提供进程继续运行的各类资源
14、数k=no1;dofor(i=0;ino1;i+)if(finishi=false)f=1;for(j=0;jworkj)f=0;if(f=1)/找到还没有完成且需求数小于可提供进程继续运行的资源数的进程finishi=true;av+=i;/记录安全序列号for(j=0;j0);f=1;for(i=0;ino1;i+)/判断是否所有的进程都完成if(finishi=false)f=0;break;if(f=0)/若有进程没完成,则为不安全状态printf(系统处在不安全状态!);r=0;elseprintf(n系统当前为安全状态,安全序列为:n);for(i=0;ino1;i+)printf(p%d,ai);/输出安全序列voidprint()/输出函数inti,j;printf(n);printf(*此时刻资源分配情况*n);printf(进程名/号|Max|Allocation|Need|n);for(i=0;ino1;i+)printf(p%d/%d,i,i);for(j=