《计算机操作系统》银行家算法实验(16页).doc
-计算机操作系统银行家算法实验-第 16 页海 南 大 学 三 亚 学 院 计算机操作系统课程设计死锁的避免银行家算法专业班级:成员:提交时间:一、问题描述(标题:宋体四号)内容:1、解释什么是银行家算法(宋体,小四,行间距1.5倍) 银行家算法又称“资源分配拒绝”法,其基本思想是,系统中的所有进程放入进程集合,在安全状态下系统受到进程的请求后试探性的把资源分配给他,现在系统将剩下的资源和进程集合中其他进程还需要的资源数做比较,找出剩余资源能满足最大需求量的进程,从而保证进程运行完成后还回全部资源。这时系统将该进程从进程集合中将其清除。此时系统中的资源就更多了。反复执行上面的步骤,最后检查进程的集合为空时就表明本次申请可行,系统处于安全状态,可以实施本次分配,否则,只要进程集合非空,系统便处于不安全状态,本次不能分配给他。请进程等待我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过了该进程对资源的最大需求量。若超过则拒绝分配资源,若没有超过则再测试系统现存的资源能否满足该进程尚需的最大资源量,若能满足则按当前的申请量分配资源,否则也要推迟分配。 2、银行家算法提出的原因 在多道程序系统中,虽可借助于多个进程的并发执行,来改善系统的 资源利用率,提高系统的吞吐量,但可能发生一种危险死锁。所谓死锁(Deadlock),是指多个进程在运行中因争夺资源而造成的一种僵局 (Deadly_Embrace),当进程处于这种僵持状态时,若无外力作用,它们都将无法再 向前推进。一组进程中,每个进程都无限等待被该组进程中另一进程所占有的资源,因而永远无法得到的资源,这种现象称为进程死锁,这一组进程就称为死锁进程。二、实验目的1、掌握死锁概念、死锁发生的原因、死锁产生的必要条件 2、掌握死锁的预防、死锁的避免 3、深刻理解死锁的避免:安全状态和银行家算法三、问题分析1、什么是死锁?死锁如何产生?所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力的作用,它们都将无法再向前推进。死锁产生的原因:(1)竞争资源(2)进程间推进顺序非法产生死锁的必要条件:互斥条件,请求和保持条件不剥夺条件,环路等待条件。只要下面四个条件中有一个不具备,系统就不会出现死锁。 互斥条件:即某个资源在一段时间内只能由一个进程占有,不能同时被两个或两个以上的进程占有。 不可抢占条件:进程所获得的资源在未使用完毕之前,资源申请者不能强行地从资源占有者手中夺取资源,而只能由该资源的占有者进程自行释放。 占有且申请条件:进程至少已经占有一个资源,但又申请新的资源;由于该资源已被另外进程占有,此时该进程阻塞;但是,它在等待新资源之时,仍继续占用已占有的资源。 循环等待条件 :存在一个进程等待序列P1,P2,Pn,其中P1等待P2所占有的某一资源,P2等待P3所占有的某一资源,而Pn等待P1所占有的某一资源,形成一个进程循环等待环。 2、死锁对多道程序系统带来的影响? 在多道程序系统中,虽可借助于多个进程的并发执行,来改善系统的 资源利用率,提高系统的吞吐量,但可能发生一种危险死锁。所谓死锁(Deadlock),是指多个进程在运行中因争夺资源而造成的一种僵局 (Deadly_Embrace),当进程处于这种僵持状态时,若无外力作用,它们都将无法再 向前推进。一组进程中,每个进程都无限等待被该组进程中另一进程所占有的资源,因而永远无法得到的资源,这种现象称为进程死锁,这一组进程就称为死锁进程。3、如何预防死锁?摒弃“请求和保持”条件,摒弃“不剥夺”条件,摒弃“环路等待”条件4、死锁的预防:什么是安全态?如何保证多个进程在某个时刻是处于安全态的?所谓安全态是指系统能按某种进程顺序(P1,P2,,Pn)(称(P1,P2,,Pn)序列为安全序列)来为每个进程Pi分配其所需资源,直至满足每个进程对资源的最大需求,使每个进程都顺利的完成。四、设计方案1、数据结构的建立1).可利用资源向量AVAILABLE。这是一个含有M个元素的数组,其中的每一个元素代表一类可利用的资源数目,其3初始值是系统中所配置的该类全部可哦那个资源的数目,其数值随该类资源的分配和回收而动态的改变。2).最大需求矩阵MAX。这是一个M*N的矩阵,它定义了系统中N个进程中的每一个进程对M类资源的最大需求。3).分配矩阵ALLOCATION。这也是一个M*N的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。4).需求矩阵NEED。这也是一个M*N的矩阵,用以表示每一个进程尚需的各类资源数。5).NEEDR,W=MAXR,W-ALLOCATIONR,W数据结构详细介绍如下:假设有M个进程N类资源,则有如下数据结构:#define W 10#define R 20int A;/总进程数int B;/资源种类int ALL_RESOURCEW; /各种资源的数目总和int MAXW; /M个进程对N类资源最大资源需求量int AVAILABLE ; /系统可用资源数int ALLOCATIONW ; /M个进程已经得到N类资源的资源量int NEEDW ; /M个进程还需要N类资源的资源量int Request ; /请求资源个数主要函数说明void showdata();/主要用来输出资源分配情况void changdata(int); /主要用来输出资源分配后后的情况void rstordata(int); /用来恢复资源分配情况,如:银行家算法时,由于分配不安全则要恢复资源分配情况int chkerr(int); /银行家分配算法的安全检查void bank();/银行家算2、算法的设计 设Requesti是进程Pi的请求向量。如果Requesti , j=k,表示Pi需k个Rj类资源。当Pi发出资源请求后,系统按下述步骤进行检查: (1) if (Requesti<=Needi) goto (2);else error(“over request”); (2) if (Requesti<=Availablei) goto (3);else wait(); (3) 系统试探性把要求资源分给Pi(类似回溯算法)。并根据分配修改下面数据结构中的值。 Availablei = Availablei Requesti ; Allocationi = Allocationi + Requesti; Needi = Needi-Requesti; (4) 系统执行安全性检查,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程以完成此次分配;若不安全,试探方案作废,恢复原资源分配表,让进程Pi等待。 系统所执行的安全性检查算法可描述如下: 设置两个向量:Free、Finish 工作向量Free是一个横向量,表示系统可提供给进程继续运行所需要的各类资源数目,它含有的元素个数等于资源数。执行安全算法开始时, Free = Available. 标记向量Finish是一个纵向量,表示进程在此次检查中中是否被满足,使之运行完成,开始时对当前未满足的进程做Finishi = false;当有足够资源分配给进程(Needi<=Free)时,Finishi=true,Pi完成,并释放资源。 (1)从进程集中找一个能满足下述条件的进程Pi Finishi = false(未定) Needi <= Free (资源够分) (2)当Pi获得资源后,认为它完成,回收资源: Free = Free + Allocationi ; Finishi = true ; Go to step(1); 试探此番若可以达到Finish0.n:=true,则表示系统处于安全状态,然后再具体为申请资源的进程分配资源。否则系统处于不安全状态。 3、算法的优化4、研究问题的推广五、方案实施1、任务划分(1)流程图初始化算法流程图银行家算法流程图:安全性算法流程图:2、具体代码#include <string.h>#include <iostream>using namespace std ;#define FALSE 0 #define TRUE 1 #define W 10 /最大进程数W=10#define R 20 /最大资源总数R=20int M ; int N ; int ALL_RESOURCEW; int AVAILABLER; /可利用资源向量int MAXWR; /最大需求矩阵int ALLOCATIONWR; /分配矩阵int NEEDWR; /需求矩阵int RequestR; /进程请求向量 void inputdata(); /数据输入 void showdata(); /数据显示 void changdata(int k);/进程请求资源数据改变void restoredata(int k); /数据恢复int chksec(int s); /系统安全性的检测int chkmax(int s); /检测最大需求 void bank(); /检测分配的资源是否合理void main() int i,j; inputdata(); for(i=0;i<M;i+) j=chksec(i); if (j=0) break; if (i>=M) cout<<"错误提示:经安全性检查发现,系统的初始状态不安全!n"<<endl; else cout<<"提示:经安全性检查发现,系统的初始状态安全!"<<endl; bank();void inputdata()int i=0,j=0,p; cout<<"请输入总进程数:"<<endl; do cin>>M; if (M>W) cout<<endl<<"总进程数超过了程序允许的最大进程数,请重新输入:"<<endl; while (M>W); cout<<endl; cout<<"请输入资源的种类数:"<<endl; do cin>>N; if (N>R)cout<<endl<<"资源的种类数超过了程序允许的最大资源种类数,请重新输入:"<<endl; while (N>R); cout<<endl; cout<<"请依次输入各类资源的总数量,即设置向量all_resource:"<<endl; for(i=0;i<N;i+) cin>>ALL_RESOURCEi; cout<<endl; cout<<"请依次输入各进程所需要的最大资源数量,即设置矩阵max:"<<endl; for (i=0;i<M;i+) for (j=0;j<N;j+) do cin>>MAXij; if (MAXij>ALL_RESOURCEj) cout<<endl<<"该最大资源数量超过了声明的该资源总数,请重新输入:"<<endl; while (MAXij>ALL_RESOURCEj); cout<<endl; cout<<"请依次输入各进程已经占据的各类资源数量,即设置矩阵allocation:"<<endl; for (i=0;i<M;i+) for (j=0;j<N;j+) docin>>ALLOCATIONij; if (ALLOCATIONij>MAXij)cout<<endl<<"已占有的资源数量超过了声明的最大资源数量,请重新输入:"<<endl; while (ALLOCATIONij>MAXij); cout<<endl; for (i=0;i<M;i+) for(j=0;j<N;j+) NEEDij=MAXij-ALLOCATIONij; for (j=0;j<N;j+) p=ALL_RESOURCEj; for (i=0;i<M;i+) p=p-ALLOCATIONij; AVAILABLEj=p; if(AVAILABLEj<0) AVAILABLEj=0;void showdata() int i,j; cout<<"各种资源的总数量,即向量all_resource为:"<<endl; cout<<" " for (j=0;j<N;j+) cout<<" 资源"<<j<<": "<<ALL_RESOURCEj; cout<<endl<<endl; cout<<"当前系统中各类资源的可用数量,即向量available为:"<<endl; cout<<" " for (j=0;j<N;j+) cout<<" 资源"<<j<<": "<<AVAILABLEj; cout<<endl<<endl; cout<<"各进程还需要的资源数量,即矩阵need为:"<<endl<<endl; for (i=0;i<M;i+) cout<<"进程P"<<i<<": " for (j=0;j<N;j+) cout<<NEEDij<<" " cout<<endl; cout<<endl; cout<<"各进程已经得到的资源量,即矩阵allocation为: "<<endl<<endl; for (i=0;i<M;i+) cout<<"进程P"<<i<<": " for (j=0;j<N;j+) cout<<ALLOCATIONij<<" " cout<<endl; cout<<endl; void changdata(int k) int j; for (j=0;j<N;j+) AVAILABLEj=AVAILABLEj-Requestj; ALLOCATIONkj=ALLOCATIONkj+Requestj; NEEDkj=NEEDkj-Requestj;void restoredata(int k) int j; for (j=0;j<N;j+) AVAILABLEj=AVAILABLEj+Requestj; ALLOCATIONkj=ALLOCATIONkj-Requestj; NEEDkj=NEEDkj+Requestj;int chksec(int s) int WORK,FINISHW; int i,j,k=0; for(i=0;i<M;i+)FINISHi=FALSE; for(j=0;j<N;j+) WORK=AVAILABLEj; i=s; doif(FINISHi=FALSE&&NEEDij<=WORK)WORK=WORK+ALLOCATIONij; FINISHi=TRUE; i=0; else i+; while(i<M); for(i=0;i<M;i+) if(FINISHi=FALSE) return 1; return 0; int chkmax(int s) int j,flag=0;for(j=0;j<N;j+) if (MAXsj=ALLOCATIONsj) flag=1;AVAILABLEj=AVAILABLEj+MAXsj;MAXsj=0;return flag;void bank() int i=0,j=0; char flag='Y' while(flag='Y'|flag='y') i=-1; while(i<0|i>=M) cout<<"请输入需申请资源的进程号(从P0到P"<<M-1<<",否则重新输入!):" cout<<"p" cin>>i; if(i<0|i>=M) cout<<"输入的进程号不存在,重新输入!"<<endl; cout<<"请输入进程P"<<i<<"申请的资源数:"<<endl; for (j=0;j<N;j+) cout<<" 资源"<<j<<": " cin>>Requestj; if(Requestj>NEEDij) cout<<"进程P"<<i<<"申请的资源数大于进程P"<<i<<"还需要"<<j<<"类资源的资源量!" cout<<"申请不合理,出错!请重新选择!"<<endl<<endl; flag='N' break; else if(Requestj>AVAILABLEj) cout<<"进程P"<<i<<"申请的资源数大于系统可用"<<j<<"类资源的资源量!" cout<<"申请不合理,出错!请重新选择!"<<endl<<endl; flag='N' break; if(flag='Y'|flag='y') changdata(i); if(chksec(i) cout<<endl; cout<<"该分配会导致系统不安全! 本次资源申请不成功,不予分配!"<<endl; cout<<endl; restoredata(i); else cout<<endl; cout<<"经安全性检查,系统安全,本次分配成功,且资源分配状况如下所示:"<<endl; cout<<endl;showdata(); if(chkmax(i)cout<<"在资源分配成功之后,由于该进程所需的某些资源的最大需求量已经满足,"<<endl;cout<<"因此在进程结束后系统将回收这些资源!"<<endl; cout<<"在资源收回之后,各进程的资源需求和分配情况如下所示:"<<endl;showdata(); cout<<endl; cout<<" 是否继续银行家算法演示,按'Y'或'y'键继续,按'N'或'n'键退出演示: " cin>>flag; 六、总结