操作系统课程设计----模拟银行家算法避免死锁
- 格式:doc
- 大小:128.50 KB
- 文档页数:11
避免死锁之银行家算法分类:Operating System2013-12-28 01:14 922人阅读评论(0) 收藏举报目录(?)[+]上篇博客中进程管理之死锁我们讲到了进程管理中死锁的各种问题,其中留下了死锁避免算法中著名的银行家算法没讲,下面就为大家详细解读。
1.安全序列讲银行家算法之前,我们首先引入安全序列的定义:所谓系统是安全的,是指系统中的所有进程能够按照某一种次序分配资源,并且依次地运行完毕,这种进程序列{P1,P2,...,Pn}就是安全序列。
如果存在这样一个安全序列,则系统是安全的;如果系统不存在这样一个安全序列,则系统是不安全的。
安全序列{P1,P2,...,Pn}是这样组成的:若对于每一个进程Pi,它需要的附加资源可以被系统中当前可用资源加上所有进程Pj当前占有资源之和所满足,则{P1,P2,...,Pn}为一个安全序列,这时系统处于安全状态,不会进入死锁状态。
虽然存在安全序列时一定不会有死锁发生,但是系统进入不安全状态(四个死锁的必要条件同时发生)也未必会产生死锁。
当然,产生死锁后,系统一定处于不安全状态。
2.银行家算法(为了熟悉英语请原谅我借用wiki上的文字来描述)For the Banker's algorithm to work, it needs to know three things:∙How much of each resource each process could possibly request[CLAIMS]∙How much of each resource each process is currently holding[ALLOCATED]∙How much of each resource the system currently has available[AVAILABLE]Resources may be allocated to a process only if it satisfies the following conditions:∙request ≤ max, else set error condition as process has crossed maximum claim made by it.∙request ≤ available, else process waits until resources are available.Basic data structures to be maintained to implement the Banker's Algorithm:∙Available: A vector of length m indicates the number of available resources of each type. If Available[j] = k, there are kinstances of resource type Rj available.∙Max: An n×m matrix defines the maximum demand of each process. If Max[i,j] = k, then Pi may request at most k instances of resource type Rj.∙Allocation: An n×m matrix defines the number of resources of each type currently allocated to each process. If Allocation[i,j] = k, then process Pi is currently allocated k instance of resourcetype Rj.∙Need: An n×m matrix indicates the remaining resource need of each process. If Need[i,j] = k, then Pi may need k moreinstances of resource type Rj to complete task.Note: Need[i,j] = Max[i,j] - Allocation[i,j].∙银行家算法:设进程i提出请求Request[j],则银行家算法按如下规则进行判断。
银行家死锁防止算法模拟之迟辟智美创作一.课程设计目的通过本次实验掌握银行家死锁防止算法的基本思想.当进程提出资源申请时,能够用该算法判断是否拒绝进程请求.二.课程设计摘要银行家算法:我们可以把把持系统看作是银行家,把持系统管理的资源相当于银行家管理的资金,进程向把持系统请求分配资源相当于用户向银行家存款.把持系统依照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最年夜需求量,如果系统现存的资源可以满足它的最年夜需求量则按以后的申请量分配资源,否则就推迟分配.当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超越了该进程对资源的最年夜需求量.若超越则拒绝分配资源,若没有超越则再测试系统现存的资源能否满足该进程尚需的最年夜资源量,若能满足则按以后的申请量分配资源,否则也要推迟分配.四.课程设计原理分析在多道法式系统中,虽可借助于多个进程的并发执行,来改善系统的资源利用率,提高系统的吞吐量,但可能发生一种危险——死锁.所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵局状态时,若无外力作用,它们都将无法再向前推进.为保证系统中诸进程的正常运行,应事先采用需要的办法,来预防死锁.最有代表性的防止死锁的方法,是Dijkstra的银行家算法.死锁:死锁的发生,必需同时满足四个条件,第一个为互斥条件,即一个资源每次只能由一个进程占用;第二个为请求和坚持条件,指进程已经坚持了至少一个资源,但又提出了新的资源请求,而该资源又被其他进程占有,此时请求进程阻塞,但又对自己已获得的其他资源坚持不放;第三个为非剥夺条件,即在呈现死锁的系统中一定有不成剥夺使用的资源;第四个为循环等候条件,系统中存在若干个循环等候的进程,即其中每一个进程分别等候它前一个进程所持有的资源.防止死锁的机构只能确保上述四个条件之一不呈现,则系统就不会发生死锁.银行家算法原理:银行家算法是防止死锁的一种重要方法,通过编写一个简单的银行家算法法式,加深了解有关资源申请、防止死锁等概念,并体会和了解死锁和防止死锁的具体实施方法.通过这个算法可以用来解决生活中的实际问题,如银行存款等.银行家算法,顾名思义是来源于银行的借贷业务,一定命量的本金要应多个客户的借贷周转,为了防止银行家资金无法周转而开张,对每一笔存款,必需考察其是否能限期归还.在把持系统中研究资源分配战略时也有类似问题,系统中有限的资源要供多个进程使用,必需保证获得的资源的进程能在有限的时间内归还资源,以供其他进程使用资源.如果资源分配不获得就会发生进程循环等候资源,则进程都无法继续执行下去的死锁现象.把一个进程需要和已占有资源的情况记录在进程控制中,假定进程控制块PCB其中“状态”有就绪态、等候态和完成态.当进程在处于等候态时,暗示系统不能满足该进程以后的资源申请.“资源需求总量”暗示进程在整个执行过程中总共要申请的资源量.显然,,每个进程的资源需求总量不能超越系统拥有的资源总数, 银行算法进行资源分配可以防止死锁.算法思想:将一定命量的资金供多个用户周转使用,当用户对资金的最年夜申请量不超越现存资金时可接纳一个新客户,客户可以分期借款,但借款总数不能超越最年夜的申请量.银行家对客户的借款可以推迟支付,可是能够使客户在有限的时间内获得借款,客户获得所有的借款后能在有限的时间内归还.用银行家算法分配资源时,测试进程对资源的最年夜需求量,若现存资源能满足最年夜需求就满足以后进程的申请,否则推迟分配,这样能够保证至少有一个进程可以获得所需的全部资源而执行到结束,然后归还资源,若OS能保证所有进程在有限的时间内获得所需资源则称系统处于平安状态.五.算法实现1.法式流程图:2.算法描述:银行家算法的设计思想是:当用户申请一组资源时,系统必需做出判断;如果把这些资源分出去,系统是否还处于平装置他.若是,就可以分出这些资源;否则,该申请暂不能满足.3.数据结构描述:(n暗示系统中进程的数目,m暗示资源的分类数.)3.1. Available是一个长度为m的向量,它暗示每类资源可用的数量.Available [j]=k,暗示rj类资源可用的数量为k. 3.是一个n×m矩阵,它暗示每个进程对资源的最年夜需求.Max [i,j]=k,暗示进程pi至多可以申请k个rj类资源单元.3.是一个n×m矩阵,它暗示以后分给每个进程的资源数目.Allocation [i,j]=k,暗示进程pi以后分到k个rj类资源.3.4. Need是一个n×m矩阵,它暗示每个进程还缺少几多资源.Need[i,j]=k,暗示进程pi尚需k个rj类资源才华完成其任务.显然Need[i,j]= Max [i,j]- Allocation [i,j].这些数据结构的年夜小和数值随时间推移而改变.4.系统所执行的平安性算法描述如下:4.1.设置2个向量:工作向量Work:它暗示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行平安算法开始时,Work = Available.Finish[i] :它暗示系统是否有足够的资源分配给进程,使之完成运行.开始时先做Finish[i]=true.4.2.从进程集合中找到一个满足下述条件的进程:Finish[i]=flase;Need[i,j]≤Work[j];若找到,则执行步伐3,否则,执行步伐4.4.3.当进程pi获得资源后,可顺利执行,直至完成,并释放分配给它的资源.4.4.如果所有进程的Finish[i]=true都满足.则暗示系统处于平安状态;否则,系统处于不服安状态.#include<iostream>#include<string>#include<stdio.h>using namespace std;#define False 0#define True 1int Max[100][100]={0};//各进程所需各类资源的最年夜需求int Avaliable[100]={0};//系统可用资源char name[100]={0};//资源的名称int Allocation[100][100]={0};//系统已分配资源int Need[100][100]={0};//还需要资源int Request[100]={0};//请求资源向量int temp[100]={0};//寄存平安序列int Work[100]={0};//寄存系统可提供资源int M=100;//作业的最年夜数为100int N=100;//资源的最年夜数为100void showdata()//显示资源矩阵{int i,j;cout<<"系统目前可用的资源[Avaliable]:"<<endl;for(i=0;i<N;i++)cout<<name[i]<<" ";cout<<endl;for (j=0;j<N;j++)cout<<Avaliable[j]<<" ";//输出分配资源cout<<endl;cout<<" Max Allocation Need"<<endl; cout<<"进程名 ";for(j=0;j<3;j++){for(i=0;i<N;i++)cout<<name[i]<<" ";cout<<" ";}cout<<endl;for(i=0;i<M;i++){cout<<" "<<i<<" ";for(j=0;j<N;j++)cout<<Max[i][j]<<" ";cout<<" ";for(j=0;j<N;j++)cout<<Allocation[i][j]<<" ";cout<<" ";for(j=0;j<N;j++)cout<<Need[i][j]<<" ";cout<<endl;}}int changdata(int i)//进行资源分配{int j;for (j=0;j<M;j++) {Avaliable[j]=Avaliable[j]-Request[j];Allocation[i][j]=Allocation[i][j]+Request[j]; Need[i][j]=Need[i][j]-Request[j];}return 1;}int safe()//平安性算法{int i,k=0,m,apply,Finish[100]={0};int j;int flag=0;Work[0]=Avaliable[0];Work[1]=Avaliable[1];Work[2]=Avaliable[2];for(i=0;i<M;i++){apply=0;for(j=0;j<N;j++){if (Finish[i]==False&&Need[i][j]<=Work[j]){ apply++;if(apply==N){for(m=0;m<N;m++)Work[m]=Work[m]+Allocation[i][m];//变分配数 Finish[i]=True;temp[k]=i;i=-1;k++;flag++;}}}}for(i=0;i<M;i++){if(Finish[i]==False){cout<<"系统不服安"<<endl;//不胜利系统不服安return -1;}}cout<<"系统是平安的!"<<endl;//如果平安,输出胜利 cout<<"分配的序列:";for(i=0;i<M;i++){//输出运行进程数组cout<<temp[i];if(i<M-1) cout<<"->";}cout<<endl;return 0;}void share()//利用银行家算法对申请资源对进行判定{char ch;int i=0,j=0;ch='y';cout<<"请输入要求分配的资源进程号(0-"<<M-1<<"):"; cin>>i;//输入须申请的资源号cout<<"请输入进程 "<<i<<" 申请的资源:"<<endl;for(j=0;j<N;j++){cout<<name[j]<<":";cin>>Request[j];//输入需要申请的资源}for (j=0;j<N;j++){if(Request[j]>Need[i][j])//判断申请是否年夜于需求,若年夜于则犯错{cout<<"进程 "<<i<<"申请的资源年夜于它需要的资源";cout<<" 分配分歧理,不予分配!"<<endl;ch='n';break;}else {if(Request[j]>Avaliable[j])//判断申请是否年夜于以后资源,若年夜于则{ //犯错cout<<"进程"<<i<<"申请的资源年夜于系统现在可利用的资源";cout<<" 分配犯错,不予分配!"<<endl;ch='n';break;}}}if(ch=='y') {changdata(i);//根据进程需求量变换资源showdata();//根据进程需求量显示变换后的资源safe();//根据进程需求量进行银行家算法判断}}void addresources(){//添加资源int n,flag;cout<<"请输入需要添加资源种类的数量:"; cin>>n;flag=N;N=N+n;for(int i=0;i<n;i++){cout<<"名称:";cin>>name[flag];cout<<"数量:";cin>>Avaliable[flag++];}showdata();safe();}void changeresources(){//修改资源函数cout<<"系统目前可用的资源[Avaliable]:"<<endl; for(int i=0;i<N;i++)cout<<name[i]<<":"<<Avaliable[i]<<endl; cout<<"输入系统可用资源[Avaliable]:"<<endl;cin>>Avaliable[0]>>Avaliable[1]>>Avaliable[2]; cout<<"经修改后的系统可用资源为"<<endl; for (int k=0;k<N;k++)cout<<name[k]<<":"<<Avaliable[k]<<endl; showdata();safe();}void delresources(){//删除资源char ming;int i,flag=1;cout<<"请输入需要删除的资源名称:";do{cin>>ming;for(i=0;i<N;i++)if(ming==name[i]){flag=0;break;}if(i==N)cout<<"该资源名称不存在,请重新输入:"; }while(flag);for(int j=i;j<N-1;j++){name[j]=name[j+1];Avaliable[j]=Avaliable[j+1];}N=N-1;showdata();safe();}void addprocess(){//添加作业int flag=M;M=M+1;cout<<"请输入该作业的最年夜需求量[Max]"<<endl; for(int i=0;i<N;i++){cout<<name[i]<<":";cin>>Max[flag][i];Need[flag][i]=Max[flag][i]-Allocation[flag][i];}showdata();safe();}int main()//主函数{int i,j,number,choice,m,n,flag;char ming;cout<<"*****************资源管理系统的设计与实现*****************"<<endl;cout<<"请首先输入系统可供资源种类的数量:"; cin>>n;N=n;for(i=0;i<n;i++){cout<<"资源"<<i+1<<"的名称:";cin>>ming;name[i]=ming;cout<<"资源的数量:";cin>>number;Avaliable[i]=number;}cout<<endl;cout<<"请输入作业的数量:";cin>>m;M=m;cout<<"请输入各进程的最年夜需求量("<<m<<"*"<<n<<"矩阵)[Max]:"<<endl;for(i=0;i<m;i++)for(j=0;j<n;j++)cin>>Max[i][j];do{flag=0;cout<<"请输入各进程已经申请的资源量("<<m<<"*"<<n<<"矩阵)[Allocation]:"<<endl;for(i=0;i<m;i++)for(j=0;j<n;j++){cin>>Allocation[i][j];if(Allocation[i][j]>Max[i][j])flag=1;Need[i][j]=Max[i][j]-Allocation[i][j];}if(flag)cout<<"申请的资源年夜于最年夜需求量,请重新输入!\n";}while(flag);showdata();//显示各种资源safe();//用银行家算法判定系统是否平安while(choice){cout<<"**************银行家算法演示***************"<<endl;cout<<" 1:增加资源 "<<endl;cout<<" 2:删除资源 "<<endl;cout<<" 3:修改资源 "<<endl;cout<<" 4:分配资源 "<<endl;cout<<" 5:增加作业 "<<endl;cout<<" 0:离开 "<<endl;cout<<"****************************************** *"<<endl;cout<<"请选择功能号:";cin>>choice;switch(choice){case 1: addresources();break;case 2: delresources();break;case 3: changeresources();break;case 4: share();break;case 5: addprocess();break;case 0: choice=0;break;default: cout<<"请正确选择功能号(0-5)!"<<endl;break; }}return 1;}调试及运行结果:检测结果如下:1.假设系统只有一种资源a,剩余数量为2,分配情况如下:2.假设系统只有一种资源a,剩余数量为2,分配情况如下:注:“系统不服安”暗示此种情况是银行家算法也解不了的死锁.3.假设系统有2种资源a,b,a的剩余数量为4,b的剩余数量为3,分配情况如下:通过本次试验,加深了自己对死锁问题和银行家算法的理解.对银行家算法的思想有了更加深刻的认识,而且意识到银行家算法其实不是能防止所有的死锁,可以称这种情况为潜在的死锁.。
操作系统实验报告-死锁的避免操作系统实验(二)死锁的避免1.实验内容使用C++实现模拟随机算法和银行家算法2.实验目的(1)了解死锁的产生原因(随机算法)(2)理解死锁的解决办法(银行家算法)3.实验题目使用随机算法和银行家算法设计程序4.程序流程图主要过程流程图银行家算法流程图安全性算法流程图5.程序代码和运行结果#include <stdio.h>#include<stdlib.h> typedef struct{int A;int B;int C;}RES;#define false 0#define true 1//系统中所有进程数量#define PNUMBER 3//最大需求矩阵RES Max[PNUMBER];//已分配资源数矩阵RES Allocation[PNUMBER];//需求矩阵RES Need[PNUMBER];//可用资源向量RES Available={0,0,0};//安全序列int safe[PNUMBER];void setConfig(){int i=0,j=0;printf("================开始手动配置资源==================\n");//可分配资源printf("输入可分配资源\n");scanf("%d%d%d",&Available.A,&Available.B,&Available.C);//最大需求矩阵MAXprintf("输入最大需求矩阵%dx%d\n",PNUMBER,PNUMBER );for (i=0;i<PNUMBER;i++){scanf("%d%d%d",&Max[i].A,&Max[i].B,&Max[i].C);}//已分配矩阵Allocprintf("输入已分配矩阵%dx%d\n",PNUMBER,PNUMBER);for (i=0;i<PNUMBER;i++){scanf("%d%d%d",&Allocation[i].A,&Allocation[i].B,&Allocation[i].C);}//需求矩阵printf("输入需求矩阵%dx%d\n",PNUMBER,PNUMBER);for (i=0;i<PNUMBER;i++){scanf("%d%d%d",&Need[i].A,&Need[i].B,&Need[i].C);}printf("================结束配置资源==================\n");}void loadConfig(){FILE *fp1;if ((fp1=fopen("config.txt","r"))==NULL){printf("没有发现配置文件,请手动输入\n");setConfig();}else{int i=0;printf("发现配置文件,开始导入..\n");//可分配资源fscanf(fp1,"%d%d%d",&Available.A,&Available.B,&Available.C);//最大需求矩阵MAXfor (i=0;i<PNUMBER;i++){fscanf(fp1,"%d%d%d",&Max[i].A,&Max[i].B,&Max[i].C);}//已分配矩阵Allocfor (i=0;i<PNUMBER;i++){fscanf(fp1,"%d%d%d",&Allocation[i].A,&Allocation[i].B,&Allocation[i].C);}//需求矩阵for (i=0;i<PNUMBER;i++){fscanf(fp1,"%d%d%d",&Need[i].A,&Need[i].B,&Need[i].C);}}}//试探分配void ProbeAlloc(int process,RES *res){Available.A -= res->A;Available.B -= res->B;Available.C -= res->C;Allocation[process].A += res->A;Allocation[process].B += res->B;Allocation[process].C += res->C;Need[process].A -= res->A;Need[process].B -= res->B;Need[process].C -= res->C;}//若试探分配后进入不安全状态,将分配回滚void RollBack(int process,RES *res){Available.A += res->A;Available.B += res->B;Available.C += res->C;Allocation[process].A -= res->A;Allocation[process].B -= res->B;Allocation[process].C -= res->C;Need[process].A += res->A;Need[process].B += res->B;Need[process].C += res->C;}//安全性检查bool SafeCheck(){RES Work;Work.A = Available.A;Work.B = Available.B;Work.C = Available.C;bool Finish[PNUMBER] = {false,false,false};int i;int j = 0;for (i = 0; i < PNUMBER; i++){//是否已检查过if(Finish[i] == false){//是否有足够的资源分配给该进程if(Need[i].A <= Work.A && Need[i].B <= Work.B && Need[i].C <= Work.C){//有则使其执行完成,并将已分配给该进程的资源全部回收Work.A += Allocation[i].A;Work.B += Allocation[i].B;Work.C += Allocation[i].C;Finish[i] = true;safe[j++] = i;i = -1; //重新进行遍历}}}//如果所有进程的Finish向量都为true则处于安全状态,否则为不安全状态for (i = 0; i < PNUMBER; i++){if (Finish[i] == false){return false;}}return true;}//资源分配请求bool request(int process,RES *res){//request向量需小于Need矩阵中对应的向量if(res->A <= Need[process].A && res->B <= Need[process].B && res->C <=Need[process].C){//request向量需小于Available向量if(res->A <= Available.A && res->B <= Available.B && res->C <= Available.C){//试探分配ProbeAlloc(process,res);//如果安全检查成立,则请求成功,否则将分配回滚并返回失败if(SafeCheck()){return true;}else{printf("安全性检查失败。
利用银行家算法避免死锁一、实现银行家算法中的几个数据结构假设n为系统中的进程数量,m为资源的种类数量,我们需要下列数据结构1)、可使用资源向量Available.为一个长度为m的数组,其中每一个元素代表该类可使用资源的数量。
其初始值为系统中所配置的该类参数全部可使用资源数目。
其数值随该类资源的分配和回收而动态地改变。
如果A vailable [j] = k 则表示系统中R j类资源有k个可被使用。
2)、最大需求矩阵Max为一个n*m的矩阵,表示系统中n个进程中的每一个进程对m类资源的最大需求。
如果Max_vector[i][j] == k 则表示进程P i需要R j类资源数目为k。
3)、已分配矩阵Allocation为一个n*m的矩阵,表示系统中每一类资源当前已分配给每一个进程的资源数。
如果allocation [i][j] == k表示进程P i当前已分配得到R j类的资源的数目为k。
4)、需求矩阵Need为一个n*m的矩阵,表示系统中每一个进程为了完成任务还需要的各类资源数目。
如果Need[i][j] == k表示进程P i还需要R j类资源k个才能完成任务。
上述数据结构之间的关系为Need[i][j] = Max[i][j] – Allocation[i][j]资源请求算法假设Request i为进程P i的请求向量。
如果Request i[j] ==k,表示进程P i需要k个Rj类型的资源。
当进程P i发出资源分配的请求之后,系统按照下述步骤进行检查。
Step1) if Request i<= Need i, go to step 2.Otherwise, raise an error condition,because the process has exceeded its maximum claim.Step2) if Request i<= A vailable, go to step3. Otherwise, P i must wait, because the rousouces are not enough.Step3) 系统试探把要求的资源分配给进程P i ,并修改下面数据结构中的数值Available = Available -Request iAllocation i = Allocation i+Request iNeed i = Need i -Request iStep4) 系统执行安全性算法,检查此次资源分配之后,系统是否处在安全状态,若安全,才正是将资源分配给进程P i,以完成本次分配;否则将试探分配作废,恢复原来的资源分配状态,让进程P i等待。
#include "malloc.h"#include "stdio.h"#include "stdlib.h"#define alloclen sizeof(struct allocation) #define maxlen sizeof(struct max)#define avalen sizeof(struct available) #define needlen sizeof(struct need)#define finilen sizeof(struct finish)#define pathlen sizeof(struct path) struct allocation{int value;struct allocation *next;};struct max{int value;struct max *next;};struct available /*可用资源数*/{int value;struct available *next;};struct need /*需求资源数*/{int value;struct need *next;};struct path{int value;struct path *next;};struct finish{int stat;struct finish *next;};int main(){int row,colum,status=0,i,j,t,temp,processtest;struct allocation *allochead,*alloc1,*alloc2,*alloctemp;struct max *maxhead,*maxium1,*maxium2,*maxtemp;struct available *avahead,*available1,*available2,*workhead,*work1,*work2,*worktemp,*worktemp1;struct need *needhead,*need1,*need2,*needtemp;struct finish *finihead,*finish1,*finish2,*finishtemp;struct path *pathhead,*path1,*path2;printf("\n请输入系统资源的种类数:");scanf("%d",&colum);printf("请输入现时内存中的进程数:");scanf("%d",&row);printf("请输入已分配资源矩阵:\n");for(i=0;i<row;i++){for (j=0;j<colum;j++){printf("请输入已分配给进程p%d 的%c 种系统资源:",i,'A'+j);if(status==0){allochead=alloc1=alloc2=(struct allocation*)malloc(alloclen);alloc1->next=alloc2->next=NULL;scanf("%d",&allochead->value);status++;}else{alloc2=(struct allocation *)malloc(alloclen);scanf("%d,%d",&alloc2->value);if(status==1){allochead->next=alloc2;status++;}alloc1->next=alloc2;alloc1=alloc2;}}}alloc2->next=NULL;status=0;printf("请输入最大需求矩阵:\n");for(i=0;i<row;i++){for (j=0;j<colum;j++){printf("请输入进程p%d 种类%c 系统资源最大需求:",i,'A'+j); if(status==0){maxhead=maxium1=maxium2=(struct max*)malloc(maxlen); maxium1->next=maxium2->next=NULL;scanf("%d",&maxium1->value);status++;}else{maxium2=(struct max *)malloc(maxlen);scanf("%d,%d",&maxium2->value);if(status==1){maxhead->next=maxium2;status++;}maxium1->next=maxium2;maxium1=maxium2;}}}maxium2->next=NULL;status=0;printf("请输入现时系统剩余的资源矩阵:\n");for (j=0;j<colum;j++){printf("种类%c 的系统资源剩余:",'A'+j);if(status==0){avahead=available1=available2=(struct available*)malloc(avalen); workhead=work1=work2=(struct available*)malloc(avalen); available1->next=available2->next=NULL;work1->next=work2->next=NULL;scanf("%d",&available1->value);work1->value=available1->value;status++;}else{available2=(struct available*)malloc(avalen);work2=(struct available*)malloc(avalen);scanf("%d,%d",&available2->value);work2->value=available2->value;if(status==1){avahead->next=available2;workhead->next=work2;status++;}available1->next=available2;available1=available2;work1->next=work2;work1=work2;}}available2->next=NULL;work2->next=NULL;status=0;alloctemp=allochead;maxtemp=maxhead;for(i=0;i<row;i++)for (j=0;j<colum;j++){if(status==0){needhead=need1=need2=(struct need*)malloc(needlen); need1->next=need2->next=NULL;need1->value=maxtemp->value-alloctemp->value; status++;}else{need2=(struct need *)malloc(needlen);need2->value=(maxtemp->value)-(alloctemp->value);if(status==1){needhead->next=need2;status++;}need1->next=need2;need1=need2;}maxtemp=maxtemp->next;alloctemp=alloctemp->next;}need2->next=NULL;status=0;for(i=0;i<row;i++){if(status==0){finihead=finish1=finish2=(struct finish*)malloc(finilen); finish1->next=finish2->next=NULL;finish1->stat=0;status++;}else{finish2=(struct finish*)malloc(finilen);finish2->stat=0;if(status==1){finihead->next=finish2;status++;}finish1->next=finish2;finish1=finish2;}}finish2->next=NULL; /*Initialization compleated*/status=0;processtest=0;for(temp=0;temp<row;temp++){alloctemp=allochead;needtemp=needhead;finishtemp=finihead;worktemp=workhead;for(i=0;i<row;i++){worktemp1=worktemp;if(finishtemp->stat==0){for(j=0;j<colum;j++,needtemp=needtemp->next,worktemp=worktemp->next) if(needtemp->value<=worktemp->value)processtest++;if(processtest==colum){for(j=0;j<colum;j++){worktemp1->value+=alloctemp->value;worktemp1=worktemp1->next;alloctemp=alloctemp->next;}if(status==0){pathhead=path1=path2=(struct path*)malloc(pathlen);path1->next=path2->next=NULL;path1->value=i;status++;}else{path2=(struct path*)malloc(pathlen);path2->value=i;if(status==1){pathhead->next=path2;status++;}path1->next=path2;path1=path2;}finishtemp->stat=1;}else{for(t=0;t<colum;t++)alloctemp=alloctemp->next; finishtemp->stat=0;}}elsefor(t=0;t<colum;t++){needtemp=needtemp->next; alloctemp=alloctemp->next;}processtest=0;worktemp=workhead;finishtemp=finishtemp->next;}}path2->next=NULL;finishtemp=finihead;for(temp=0;temp<row;temp++){if(finishtemp->stat==0){printf("\n系统处于非安全状态!\n"); exit(0);}finishtemp=finishtemp->next;}printf("\n系统处于安全状态.\n"); printf("\n安全序列为: \n");do{printf("p%d ",pathhead->value);}while(pathhead=pathhead->next); printf("\n");return 0;}。
计算机与信息工程系《计算机系统与系统软件》课程设计报告题目:模拟实现银行家算法实现死锁避免专业:信息管理与信息系统班级:信管082班学号:姓名:指导老师:2010年9 月9 日一、实验题目模拟实现银行家算法实现死锁避免二、目的:1、了解进程产生死锁的原因,了解为什么要进行死锁的避免。
2、掌握银行家算法的数据结构,了解算法的执行过程,加深对银行家算法的理解。
三、内容:模拟实现银行家算法实现死锁避免。
要求:初始数据(如系统在T0时刻的资源分配情况、每一种资源的总数量)从文本文件读入,文件中给出最大需求矩阵Max、分配矩阵Allocation,在程序中求得需求矩阵Need和可利用资源向量Available。
四、实验提示:1、整个银行家算法的思路。
先对用户提出的请求进行合法性检查,再进行预分配,利用安全性检查算法进行安全性检查。
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]。
如果条件不符则提示重新输入,即不允许索取大于需求量(4)、检查用户的请求是否小于系统中的可利用资源数量,条件是K<=A V ALIABLE[I,J]。
《操作系统--课程设计报告》银行家算法姓名:学号:专业:指导老师:目录一、设计目的 (1)二、设计要求 (1)三、设计内容和步骤 (1)四、算法描述 (6)五、实验结果 (12)六、实验心得 (12)一、设计目的银行家算法是避免死锁的一种重要方法,本实验要求用高级语言编写和调试一个简单的银行家算法程序。
加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。
二、设计要求在了解和掌握银行家算法的基础上,能熟练的处理课本例题中所给状态的安全性问题,能编制银行家算法通用程序,将调试结果显示在计算机屏幕上。
具体程序的功能要求:1.设定进程对各类资源最大申请表示及初值确定。
2.设定系统提供资源初始状况(已分配资源、可用资源)。
3.设定每次某个进程对各类资源的申请表示。
4.编制程序,依据银行家算法,决定其申请是否得到满足。
三、设计内容和步骤设计内容银行家算法的思路:先对用户提出的请求进行合法性检查,即检查请求的是不大于需要的,是否不大于可利用的。
若请求合法,则进行试分配。
最后对试分配后的状态调用安全性检查算法进行安全性检查。
若安全,则分配,否则,不分配,恢复原来状态,拒绝申请。
设计步骤1、为实现银行家算法,系统中需要设置若干数据结构,用来表示系统中各进程的资源分配及需求情况。
假定系统中有M个进程,N类资源。
进程数和资源数由程序中直接定义#define M 5 //总进程数#define N 3 //总资源数银行家算法中使用的数据结构如下:(1)可利用资源Available。
这是一个含有m个元素的数组,其中的每一个元素代表一类资源的空闲资源数目,其初值是系统中所配置的该类资源的数目,其数值随该类资源的分配和回收而动态的改变。
如果Available[j]=k,表示系统中Rj类资源有k个。
(2)最大需求矩阵Max。
这是一个n*m的矩阵,它定义了系统中每一个进程对各类资源的最大需求数目。
如果Max[i,j]=k,表示进程Pi对Rj类资源的最大需求数为k个。
内容摘要本课设要完成的是编写一程序,能够模拟银行家算法和安全算法来避免死锁的问题。
我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。
当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过了该进程对资源的最大需求量。
若超过则拒绝分配资源,若没有超过则再测试系统现存的资源能否满足该进程尚需的最大资源量,若能满足则按当前的申请量分配资源,否则也要推迟分配。
关键词银行家算法C语言数据结构课程设计任务书目录:第一章绪论 (4)1.1 综述 (4)1.2设计内容与要求 (5)1.3 设计目的 (5)1.4设计地点 (5)1.5设计环境 (5)第二章程序设计与实现 (6)2 .1详细设计 (6)2.1 .1银行家算法数据结构设计描述 (6)2.1.2银行家算法实现描述 (6)2.1.3 程序流程图 (7)第三章程序调试与运行 (8)3.1运行结果 (8)第四章实验体会 (10)参考文献 (11)附录: (11)第一章绪论1.1 综述操作系统是现代计算机系统中最基本和最重要的系统软件,它是计算机科学与技术专业的一门重要的基础课程。
通过讲授本课程,学生可以全面的了解操作系统的概念,操作系统是一组能有效的组织和管理计算机硬件和软件资源,合理地对各类资源进行调度,以方便用户使用的程序的集合。
其作用是管理好这些设备,提高利用率和系统的吞吐量,为用户和应用程序提供简单的接口,便于用户使用。
学完操作系统,可以更好的搭建学生的专业基础知识。
本次课程设计在本着加强课本知识运用能力的前提下,老师给出银行家算法这个题目。
该题目主要是解决利用银行家算法和安全算法来避免死锁的问题。
计算机操纵系统实验陈述之袁州冬雪创作题目操纵银行家算法防止死锁一、实验目标:1、加深懂得有关资源申请、防止死锁等概念,并体会和懂得死锁和防止死锁的详细实施方法.2、要求编写和调试一个系统动态分配资源的简单摹拟程序,观察死锁发生的条件,并采取银行家算法,有效的防止和防止死锁的发生.二、实验内容:用银行家算法实现资源分配:设计五个过程{p0,p1,p2,p3,p4}共享三类资源{A,B,C}的系统,例如,{A,B,C}的资源数量分别为10,5,7.过程可动态地申请资源和释放资源,系统按过程的申请动态地分配资源,要求程序具有显示和打印各过程的某一个时刻的资源分配表和平安序列;显示和打印各过程依次要求申请的资源号以及为某过程分配资源后的有关资源数据.三、问题分析与设计:1、算法思路:先对用户提出的请求停止合法性检查,即检查请求是否大于需要的,是否大于可操纵的.若请求合法,则停止预分配,对分配后的状态调用平安性算法停止检查.若平安,则分配;若不服安,则回绝申请,恢复到原来的状态,回绝申请.2、银行家算法步调:(1)如果Requesti<or =Need,则转向步调(2);否则,认为出错,因为它所需要的资源数已超出它所宣布的最大值.(2)如果Request<or=Available,则转向步调(3);否则,暗示系统中尚无足够的资源,过程必须等待.(3)系统试探把要求的资源分配给过程Pi,并修改下面数据布局中的数值:Available=Available-Request[i];Allocation=Allocation+Request;Need=Need-Request;(4)系统执行平安性算法,检查此次资源分配后,系统是否处于平安状态.3、平安性算法步调:(1)设置两个向量①工作向量Work.它暗示系统可提供过程继续运行所需要的各类资源数目,执行平安算法开端时,Work=Allocation;②布尔向量Finish.它暗示系统是否有足够的资源分配给过程,使之运行完成,开端时先做Finish[i]=false,当有足够资源分配给过程时,令Finish[i]=true.(2)从过程集合中找到一个能知足下述条件的过程:①Finish[i]=false②Need<or=Work如找到,执行步调(3);否则,执行步调(4).(3)当过程P获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:Work=Work+Allocation;Finish[i]=true;转向步调(2).(4)如果所有过程的Finish[i]=true,则暗示系统处于平安状态;否则,系统处于不服安状态.4、流程图:系统主要过程流程图银行家算法流程图平安性算法流程图5、主要数据布局假设有M个过程N类资源,则有如下数据布局:int max[M*N] M个过程对N类资源的最大需求量int available[N] 系统可用资源数int allocated[M*N] M个过程已经得到N类资源的资源量int need[M*N] M个过程还需要N类资源的资源量int worked[] 系统提供给过程继续运行所需的各类资源数目四、源代码import java.awt.*;import javax.swing.*;import java.util.*;import java.awt.event.*;import javax.swing.border.*;public class OsBanker extends JFrame { // 界面设计JLabel labelInfo;JLabel labelInfo1;int resourceNum, processNum;int count = 0;JButton buttonRequest, buttonSetInit, button, button1, buttonsearch,button2;JTextField tf1, tf2;JTextField[] textAvailable;JTextField[][] textAllocation;JTextField[][] textNeed;JTextField textProcessName;JTextField[] textRequest;int available[];int max[][];int need[][];int allocated[][];int SafeSequence[];int request[];boolean Finish[];int worked[];boolean flag = false;JFrame f1;JFrame f2;JFrame f3;JTextArea jt;void display() {Border border = BorderFactory.createLoweredBevelBorder();Border borderTitled = BorderFactory.createTitledBorder(border, "按钮区"); textAvailable = new JTextField[5];textAllocation = new JTextField[6][5];textNeed = new JTextField[6][5];textProcessName = new JTextField(""); textProcessName.setEnabled(false);textRequest = new JTextField[5];tf1 = new JTextField(20);tf2 = new JTextField(20);labelInfo = new JLabel("请先输入资源个数和过程个数(1~6),后单击确定");JPanel contentPane;contentPane = (JPanel) this.getContentPane(); contentPane.setLayout(null);contentPane.setBackground(Color.pink);labelInfo.setBounds(50, 10, 300, 40);labelInfo.setOpaque(true);labelInfo.setForeground(Color.red);labelInfo.setBackground(Color.pink);contentPane.add(labelInfo, null);JLabel b1 = new JLabel("资源个数:");b1.setForeground(Color.blue);JLabel b2 = new JLabel("过程个数:");b2.setForeground(Color.blue);b1.setBounds(50, 80, 80, 30);contentPane.add(b1, null);tf1.setBounds(180, 80, 170, 30);contentPane.add(tf1, null);b2.setBounds(50, 150, 80, 30);contentPane.add(b2, null);tf2.setBounds(180, 150, 170, 30);contentPane.add(tf2, null);button1 = new JButton("确定");button = new JButton("重置");button1.setBounds(80, 200, 80, 30);contentPane.add(button1, null);button.setBounds(220, 200, 80, 30);contentPane.add(button, null);this.setSize(400, 300);this.setResizable(false);this.setTitle("银行家算法(SXJ)");this.setLocationRelativeTo(null);this.setDefaultClo搜索引擎优化peration(EXIT_ON_CLOSE);this.setVisible(true);f1 = new JFrame();labelInfo1 = new JLabel("请先输入最大需求和分配矩阵,然后单击初始化");JPanel contentPane1;contentPane1 = (JPanel) f1.getContentPane(); contentPane1.setLayout(null);contentPane1.setBackground(Color.pink);labelInfo1.setOpaque(true);labelInfo1.setBounds(75, 10, 400, 40);labelInfo1.setBackground(Color.pink);labelInfo1.setForeground(Color.blue);contentPane1.add(labelInfo1, null);JLabel labelAvailableLabel = new JLabel("AllResource:");JLabel labelNeedLabel = new JLabel("MaxNeed:"); JLabel labelAllocationLabel = new JLabel("allocated:");JLabel labelRequestLabel = new JLabel("request process:");labelNeedLabel.setBounds(75, 90, 100, 20);// x,y,width,heightcontentPane1.add(labelNeedLabel, null); labelAllocationLabel.setBounds(75, 240, 100, 20); contentPane1.add(labelAllocationLabel, null); labelAvailableLabel.setBounds(75, 70, 100, 20); contentPane1.add(labelAvailableLabel, null); labelRequestLabel.setBounds(75, 400, 100, 20); contentPane1.add(labelRequestLabel, null);JLabel[] labelProcessLabel1 = { new JLabel("过程1"), new JLabel("过程2"),new JLabel("过程3"), new JLabel("过程4"), new JLabel("过程5"),new JLabel("过程6") };JLabel[] labelProcessLabel2 = { new JLabel("过程1"), new JLabel("过程2"),new JLabel("过程3"), new JLabel("过程4"), new JLabel("过程5"),new JLabel("过程6") };JPanel pPanel1 = new JPanel(), pPanel2 = new JPanel(), pPanel3 = new JPanel(), pPanel4 = new JPanel();pPanel1.setLayout(null);pPanel2.setLayout(null);/** pPanel4.setLayout(null); pPanel4.setBounds(440,120,90,270);* pPanel4.setBorder(borderTitled);*/buttonSetInit = new JButton("初始化");buttonsearch = new JButton("检测平安性");button2 = new JButton("重置");buttonRequest = new JButton("请求资源"); buttonSetInit.setBounds(420, 140, 100, 30); contentPane1.add(buttonSetInit, null);buttonsearch.setBounds(420, 240, 100, 30); contentPane1.add(buttonsearch, null);button2.setBounds(420, 340, 100, 30);contentPane1.add(button2, null);buttonRequest.setBounds(420, 425, 100, 30); contentPane1.add(buttonRequest, null);for (int pi = 0; pi < 6; pi++) {labelProcessLabel1[pi].setBounds(0, 0 + pi * 20, 60, 20);labelProcessLabel2[pi].setBounds(0, 0 + pi * 20, 60, 20);}pPanel1.setBounds(75, 120, 60, 120);pPanel2.setBounds(75, 270, 60, 120);for (int pi = 0; pi < 6; pi++) {pPanel1.add(labelProcessLabel1[pi], null);pPanel2.add(labelProcessLabel2[pi], null);}contentPane1.add(pPanel1);contentPane1.add(pPanel2);contentPane1.add(pPanel4);for (int si = 0; si < 5; si++)for (int pi = 0; pi < 6; pi++) {textNeed[pi][si] = new JTextField();textNeed[pi][si].setBounds(150 + si * 50, 120 + pi * 20, 50, 20); textNeed[pi][si].setEditable(false);textAllocation[pi][si] = new JTextField(); textAllocation[pi][si].setBounds(150 + si * 50, 270 + pi * 20,50, 20);textAllocation[pi][si].setEditable(false);}for (int si = 0; si < 5; si++) {textAvailable[si] = new JTextField();textAvailable[si].setEditable(false);textAvailable[si].setBounds(150 + si * 50, 70, 50, 20);textRequest[si] = new JTextField();textRequest[si].setEditable(false);textRequest[si].setBounds(150 + si * 50, 430, 50, 20);contentPane1.add(textAvailable[si], null); contentPane1.add(textRequest[si], null);}for (int pi = 0; pi < 6; pi++)for (int si = 0; si < 5; si++) {contentPane1.add(textNeed[pi][si], null); contentPane1.add(textAllocation[pi][si], null);}textProcessName.setBounds(80, 430, 50, 20); contentPane1.add(textProcessName, null);f1.setSize(550, 500);f1.setResizable(false);f1.setTitle("银行家算法(SXJ)");f1.setLocationRelativeTo(null);f1.setDefaultClo搜索引擎优化peration(EXIT_ON_CLOSE);// f1.setVisible(true);f1.setVisible(false);f2 = new JFrame("平安序列显示框");jt = new JTextArea(75, 40);jt.setBackground(Color.pink);jt.setForeground(Color.blue);JScrollPane scrollPane = new JScrollPane(jt); // 加滚动条scrollPane.setBorder(BorderFactory.createLoweredBev elBorder());// 鸿沟(f2.getContentPane()).add(scrollPane);f2.setSize(450, 400);f2.setResizable(false);f2.setDefaultClo搜索引擎优化peration(EXIT_ON_CLOSE);f2.setVisible(false);buttonSetInit.setEnabled(false);buttonRequest.setEnabled(false);buttonsearch.setEnabled(false);button1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {// labelInfo.setText("请先初始化allocated和Maxneed,后单击初始化按钮");f1.setVisible(true);buttonSetInit.setEnabled(true);resourceNum = Integer.parseInt(tf1.getText());processNum = Integer.parseInt(tf2.getText());for (int i = 0; i < processNum; i++) {for (int j = 0; j < resourceNum; j++) {textNeed[i][j].setEditable(true);textAllocation[i][j].setEditable(true);textAvailable[j].setEditable(true);}}}});buttonSetInit.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {Init();buttonsearch.setEnabled(true);}});buttonsearch.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {count = 0;SafeSequence = new int[processNum];worked = new int[resourceNum];Finish = new boolean[processNum];copyVector(worked, available);Safety(0);jt.append("平安序列数量:" + count);if (flag) {labelInfo1.setText("当前系统状态:平安");f2.setVisible(true);buttonRequest.setEnabled(true);textProcessName.setEnabled(true);for (int i = 0; i < resourceNum; i++) {textRequest[i].setEditable(true);}} else {labelInfo1.setText("当前系统状态:不服安");}buttonSetInit.setEnabled(false);}});buttonRequest.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {count = 0;for (int i = 0; i < processNum; i++) {Finish[i] = false;}jt.setText("");flag = false;RequestResource();}});button2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {/** tf1.setText(""); tf2.setText("");*/f2.setVisible(false);jt.setText("");for (int i = 0; i < processNum; i++) {for (int j = 0; j < resourceNum; j++) { textNeed[i][j].setText("");textAllocation[i][j].setText("");textAvailable[j].setText("");textRequest[j].setText("");// textNeed[i][j].setEditable(false);// textAllocation[i][j].setEditable(false);// textAvailable[j].setEditable(false);textRequest[j].setEditable(false); textProcessName.setText("");Finish[i] = false;}}flag = false;buttonsearch.setEnabled(false);// labelInfo.setText("请先输入资源个数和过程个数,后单击确定");}});button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {tf1.setText("");tf2.setText("");f2.setVisible(false);jt.setText("");flag = false;}});}void copyVector(int[] v1, int[] v2) { for (int i = 0; i < v1.length; i++)v1[i] = v2[i];}void Add(int[] v1, int[] v2) {for (int i = 0; i < v1.length; i++)v1[i] += v2[i];}void Sub(int[] v1, int[] v2) {for (int i = 0; i < v1.length; i++) v1[i] -= v2[i];}boolean Smaller(int[] v1, int[] v2) { boolean value = true;for (int i = 0; i < v1.length; i++)if (v1[i] > v2[i]) {value = false;break;}return value;}public static void main(String[] args) {OsBanker ob = new OsBanker();ob.display();// System.out.println(" "+count);}void Init() // 初始化操纵矩阵{available = new int[resourceNum];for (int i = 0; i < resourceNum; i++) {available[i] = Integer.parseInt(textAvailable[i].getText());}max = new int[processNum][resourceNum];allocated = new int[processNum][resourceNum];need = new int[processNum][resourceNum];for (int i = 0; i < processNum; i++) {for (int j = 0; j < resourceNum; j++) {max[i][j] = Integer.parseInt(textNeed[i][j].getText());allocated[i][j] = Integer.parseInt(textAllocation[i][j].getText());}}for (int i = 0; i < resourceNum; i++)for (int j = 0; j < processNum; j++)need[j][i] = max[j][i] - allocated[j][i];for (int i = 0; i < resourceNum; i++)for (int j = 0; j < processNum; j++) {available[i] -= allocated[j][i];if (available[i] < 0) {labelInfo.setText("您输入的数占有误,请重新输入"); }}}void Safety(int n) // 查找所有平安序列{if (n == processNum) {count++;for (int i = 0; i < processNum; i++) {jt.append("过程" + (SafeSequence[i] + 1) + " "); }jt.append("\n");flag = true;return;}for (int i = 0; i < processNum; i++) { if (Finish[i] == false) {boolean OK = true;for (int j = 0; j < resourceNum; j++) { if (need[i][j] > worked[j]) {OK = false;break;}}if (OK) {for (int j = 0; j < resourceNum; j++) { worked[j] += allocated[i][j];}Finish[i] = true;SafeSequence[n] = i;Safety(n + 1);Finish[i] = false;SafeSequence[n] = -1;// num++;for (int j = 0; j < resourceNum; j++) {worked[j] -= allocated[i][j];}}}}}void RequestResource() { // 请求资源jt.setText("");int processname = (Integer.parseInt(textProcessName.getText()) - 1); request = new int[resourceNum];for (int i = 0; i < resourceNum; i++) {request[i] = Integer.parseInt(textRequest[i].getText());}if (!Smaller(request, need[processname])) { labelInfo.setText("资源请求不符该过程的需求量.");} else if (!Smaller(request, available)) {labelInfo1.setText("可用资源缺乏以知足请求,过程需要等待.");} else {Sub(available, request);Add(allocated[processname], request);Sub(need[processname], request);copyVector(worked, available);Safety(0);if (flag) {labelInfo1.setText("可当即分配给该过程!");} else {labelInfo1.setText("分配后导致系统处于不服安状态!,不成当即分配");Add(available, request);Sub(allocated[processname], request);Add(need[processname], request);}}// }}}五、实验成果:初始界面:初始化:检测平安性:请求资源:(1)过程2(1,0,2)(2)过程5(3,3,0)(3)过程1(0,2,0)六、遇到的问题及缺乏之处:1、程序编写的时候规定最大资源数和最大过程数均<=6.2、程序直接初始化了6个过程框,既华侈了内存空间,又对可视化界面的雅观造成影响.3、未对输入异常停止处理:比方在请求资源的第一个方框中只能填入过程的数字编号,当填入的为非整数时,程序会抛出异常.4、未处理过程名中对字符串的处理,直接固定过程名为数字,用户不克不及直接输入原有的过程名,造成欠好的用户体验.。
采用银行家算法避免死锁一、实验目的:观察死锁发生的现象,了解死锁发生的原因。
掌握如何判断死锁发生的方法。
二、实验分析:死锁现象是操作系统各个进程竞争系统中有限的资源引起的。
如果随机给进程分配资源,就可能发生死锁,因此就应有办法检测死锁的发生。
本次实验中采用“银行家算法”判断死锁的发生。
三、实验设计:本实验设计一个3个并发进程共享3种系统资源且每种系统资源有10个的系统。
系统能显示各种进程的进展情况以及检察是否有错误和死锁现象产生。
四、算法说明:“银行家算法”。
按每个进程的申请数量给各个进程试探性分配资源,看能否找到一个序列使各个进程都能正常运行结束。
若能,则不会发生死锁;若不能,则会发生死锁。
五、程序使用说明:1、本程序用于检测错误和是否会发生死锁。
系统有3个进程竞争3种系统资源,每种资源有10个。
2、输入各个进程的最大需求资源数目数组max[3]和已经得到的资源数目数组alloc [3],系统计算出各个进程还应申请的资源数目数组need[3]。
3、若进程最大需求数大于系统资源数(10),则出错;若进程申请的资源数目大于其需要的最大资源数目,则出错。
银行家算法的具体实现程序:#include <stdio.h>#define R 10#define P 10int SafeCheck(int n,int m,int Max[P][R],int Allocation[P][R],int Available[R],int Need[P][R]){int p,i,j, safeque[P],Work[R],Finish[P]={0},t=0,flag;printf("当前的工作向量为:");for(j=0;j<m;j++){Work[j]=Available[j];printf("%d,",Work[j]);}//设置Work向量while(t<n){//开始寻找可分配的进程for(i=0;i<n;i++){if(Finish[i]==1) flag=0;//跳过已分配结束的进程else flag=1;if(flag){p=i;for(j=0;j<m;j++)if(Need[p][j]>Work[j]) { p=-1; break; }}if(p==i){ printf("找到一个可分配的进程P%d!\n",p); break;} }//顺序循环查找可分配资源的进程if(p!=-1){safeque[t++]=p;//入栈保护Finish[p]=1;//标志该进程结束printf("当前的工作向量为:");for(j=0;j<m;j++){Work[j]+=Allocation[p][j];printf("%d,",Work[j]);}p=-1;//清空当前进程号,以便下一次寻找出新的进程}//找到可分配资源的进程,并重设Work向量else { printf("找不到一个可分配的进程!终止检查!"); break; } }if(t==n){printf("系统存在一个安全序列:");for(t=0;t<n;t++)printf("P%d->",safeque[t]);printf("\n");return 1;}else {printf("系统不安全!会产生死锁!\n"); return 0;}}void main(){int Available[R],Max[P][R],Allocation[P][R],Need[P][R];int i,n,m,j,p,Request[R];int safe1,safe2;//设置第一次检查与第二次检查正确与否的观察变量printf("输入进程总数:");scanf("%d",&n);printf("输入资源类数:");scanf("%d",&m);printf("系统中R0--R%d类资源可利用数(空格隔开):",m-1);for(i=0;i<m;i++){scanf("%d",&Available[i]);}for(i=0;i<n;i++){printf("P%d进程的每类资源的分配情况如下:\n",i);printf("\tR0--R%d类资源最大数(空格隔开):",m-1);for(j=0;j<m;j++){scanf("%d",&Max[i][j]);}printf("\tR0--R%d类资源已分配(空格隔开):",m-1);for(j=0;j<m;j++){scanf("%d",&Allocation[i][j]);Need[i][j]=Max[i][j]-Allocation[i][j];}printf("\tR0--R%d类资源需求数(空格隔开):",m-1);for(j=0;j<m;j++){printf("%d ",Need[i][j]);}printf("\n");}//初始化进程的资源分配表printf("——————-第一次安全性检查——————\n");safe1=SafeCheck(n,m,Max,Allocation,Available,Need);if(safe1){printf("输入请求请求进程P的进程号:");scanf("%d",&p);printf("输入请求的R0--R%d各类资源数(空格隔开):",m-1);for(j=0;j<m;j++){scanf("%d",&Request[j]);if(Request[j]>Need[p][j]){printf("所请求的该资源数大于该进程所需求的最大值!终止请求!");safe1=0;break;}if(Request[j]>Available[j]){printf("所请求的该资源数大于系统中所拥有的最大值!终止请求!");safe1=0;break;}}}//第一次安全检查系统安全后判断请求向量的正确性if(safe1){printf("——————-第二次安全性检查——————\n");for(j=0;j<m;j++){Allocation[p][j]+=Request[j];Need[p][j]=Max[p][j]-Allocation[p][j];Available[j]-=Request[j];}//第二次安全检查前试探分配资源给请求资源safe2=SafeCheck(n,m,Max,Allocation,Available,Need);if(safe2==0)for(j=0;j<m;j++){Allocation[p][j]-=Request[j];Need[p][j]=Max[p][j]-Allocation[p][j];Available[j]+=Request[j];}//安全检查失败后重新收回分配给请求进程的资源}}书上的银行家算法例题实现如下:分析:该程序找到的安全序列:第一次检查{p1,p3,p0,p2,p4}第二次检查{p1,p3,p0,p2,p4}虽然与书上例题不一致,但经检验可以找出如上安全序列。
操作系统实验二死锁的避免——银行家算法一、实验目的银行家算法是避免死锁的一种重要算法,本实验要求用高级语言编写和调试一个简单的银行家算法程序。
加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。
二、实验要求:编制程序, 依据银行家算法判定本次分配是否安全。
三.算法所用數據結構讲解1.数据结构假设有m个进程N类资源,则有如下数据结构MAX[M*N] M个进程对N 类资源的最大需求量;A V AILABEL[N] 系统可用资源数;ALLOCATION[M*N] M个进程已得到N 类资源的资源量;NEED[M*N] M个进程还需要N 类资源的资源量;2.行家算法设进程I 提出请求Request[N],则(1)若Request[N]<= NEED[I,N],则转(2);否则出错。
(2)若NEED[I,N] <= A V AILABEL[N],则转3;否则出错。
3.安全性检查(1)从进程集合中找到一个能满足下述条件的进程:①Finish[i]=false; ②Needi≤Work.如找到,执行步骤(2);否则执行步骤(3)。
(2)当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故执行:Work:=Work+Allocation; Finish[i]:=true; Goto step1;(3)如果所有进程的Finish[i]=true,则表示系统处于安全状态;否则,系统处于不安全状态。
四.实验报告要求1.写出实验目的2。
写出实验要求3。
写出实验内容(包括算法,程序流程图及部分实验结果)4.实验总结与体会附:#include "stdio.h"#define M 5 /*总进程数*/#define N 3 /*总资源数*/#define FALSE 0#define TRUE 1/*M个进程对N类资源最大资源需求量*/int MAX[M][N]= {{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};/*系统可用资源数*/int A V AILABLE[N]={3,3,2};/* M个进程已经得到N类资源的资源量*/int ALLOCATION[M][N]={{0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2}};/* M个进程还需要N类资源的资源量*/int NEED[M][N]={{7,4,3},{1,2,2},{6,0,0},{0,1,1},{4,3,1}};int Request[N]={0,0,0};int i=0,j=0;void main(){char flag='Y';void showdata();void changdata(int);void rstordata(int);int chkerr(int);showdata();while (flag=='Y'||flag=='y'){printf("输入申请资源的进程号(0~4):");scanf("%d",&i);while (i<0||i>=M){printf("输入的进程号不存在,请重输入申请资源的进程号(0~4):");scanf("%d",&i);}for(j=0;j<N;j++){printf("申请资源%d :",j);scanf("%d",&Request[j]);if (Request[j]>NEED[i][j]){printf("进程%d申请的资源数大于进程%d还需要%d类资源的资源量!",i,i,j);printf("申请不合理,出错!请重新选择\n");exit(0);}else{if (Request[j]>A V AILABLE[j]){printf("进程%d 申请的资源数大于系统可用%d类资源的资源量!",i,j);printf("本次分配不成功。
华南理工“计算机操作系统”课程设计大作业一、实验题目: 银行家死锁避免算法模拟二、实验目的:通过本次实验掌握银行家死锁避免算法的基本思想。
当进程提出资源申请时,能够用该算法判断是否拒绝进程请求。
三、实验内容认真阅读教材(计算机操作系统(第三版),汤小丹,西安电子科技大学出版社)P108-P111页3.6.3节银行家算法的实现思想,理解该算法是如何能够实现死锁避免的。
编写一个银行家算法模拟程序用于处理进程的资源申请。
1。
假设系统共有5类资源,分别以A、B、C、D、E来标识,每类资源的初始数量全部为50。
2。
进程可以通过程序界面随时提交新的资源申请,提交的信息包括进程名称、对5类资源的最大需求数量。
3。
每次当有资源申请时,先输出系统当前状态(5类资源当前可用数量,每个进程已分配的每类资源数量),再利用银行家算法判断是否该满足进程请求。
如果可以分配,输出给该进程分配资源后的系统状态,再输出至少一个“安全序列”。
四、实验要求:每人完成一份大作业实验报告。
报告分设计思想、数据定义、处理流程、源程序、运行结果截图、设计体会等部分。
1)给出数据定义和详细说明;2)给出实现思想和设计流程;3)调试完成源程序;4)屏幕观察运行结果;5)总结自己的设计体会;编程语言及操作系统平台不限。
五、提交内容本大作业每个人必须单独完成。
最后需提交的内容包括:源程序(关键代码需要注释说明)、可运行程序、算法思路及流程图、心得体会。
将以上内容刻入光盘,光盘上写明班级、学号、姓名信息,再将大作业要求、源程序及注释、算法思路及流程图、心得体会等打印出来。
最后将打印稿及光盘统一交给网络学院教务员。
银行家算法实现一.课程设计目的1. 加深对死锁概念的理解。
2. 能够利用银行家算法,有效避免死锁的发生,或检测死锁的存在。
二.课程设计摘要银行家算法:我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
实验六银行家算法避免死锁一.实验目的1、加深对死锁概念的理解2、能够利用银行家算法有效地避免死锁的发生、或检测死锁的存在二.实验内容及步骤本实验在winTC环境下实现,winTC安装程序在ftp上,请自行安装。
1.利用银行家算法写一个程序,判定系统的安全性。
已知某系统有5个进程P0,P1,P2,P3,P4,三类资源A、B、C。
死锁检测程序工作时0)。
#define m 3#define n 5main(){int test(int av[],int ned[],all[]);int available[m]={0,0,0},need[n][m];int allocation[n][m]={{0,1,0},{2,0,0},{3,0,3},{2,1,1},{0,0,2}};//已占有资源int i,j,g=1;int finish[n]={0,0,0,0,0};//已完成的进程clrscr();//清屏printf(“please input the need resource data\n”);for(i=0;i<n;i++)for(j=0;j<m;j++)scanf(“%d”,&need[i][j]);//输入各个进程需要的资源j=0;do{for(i=0;i<n;i++)if(finish[i]==0 && test(need[i],available,allocation[i])) finish[i]=1;j++;}while(j<n);for(i=0;i<n;i++)g=g&&finish[i];//判断各个进程是否在安全性算法内全部通过if(g)printf(“safe state”);elseprintf(“not safe state”);}三.实验讨论谈谈你今天上实验课的收获,存在的问题或疑问。
如果有实验内容以外的发现也可谈谈。
操作系统实验报告死锁避免算法的模拟实验——银行家算法班级:2013级软件工程1班学号:X X X姓名:萧氏一郎数据结构说明:①可利用资源向量available, n个元素的数组,每个元素代表一类可用资源的数目, available [ i ] = k,表示系统中有Rj 类资源k 个。
②最大需求矩阵MAX, n3 m矩阵定义n 个进程时,m 类资源的最大需求max ( i, j) = k 表示进程需要Rj类资源最大数目为k 。
③分配矩阵allocation, n3 m矩阵,表示n个进程的每个进程已分配资源情况, alloction ( i, j) = k表示进程i已分配Rj类资源k 个。
④需求矩阵need, n3 m矩阵,表示各进程仍需要各类资源, need ( i, j) = k表示进程i仍需要资源Rj的数目为k.由上述分析可知need i =max i - allocation i。
流程图:源代码:#include<stdio.h>int Isprocessallover(); //判断系统中的进程是否全部运行完毕void Systemstatus(); //显示当前系统中的资源及进程情况void Allow(int ,int *); //若进程申请不导致死锁,用此函数分配资源void Forbidenseason(int ); //若发生死锁,则显示原因int Banker(int ,int *); //银行家算法int Availiable[5] = { 5,6, 6,5,4}; //初始状态,系统可用资源量int Max[5][5] = {{1,2,3,2,3},{3,2,2,3,3},{7,0,2,3,3},{2,2,2,2,3},{4,3,3,1,3 }}; //各进程对各资源的最大需求量intAllocation[5][5]={{0,1,0,0,1},{2,0,0,1,1},{3,0,2,0,1},{2,1, 1,0,1},{0,0,2,0,1},}; //初始状态,各进程占有资源量intNeed[5][5]={{1,1,3,2,2},{1,2,2,2,2},{4,0,0,3,2},{0,1,1,2,2} ,{4,3,1,1,2},}; //初始状态时,各进程运行完毕,还需要的资源量int over[5]={0,0,0,0,0}; //标记对应进程是否得到所有资源并运行完毕int main(){int i,j,k;int process=0; //发出请求的进程int decide=0; //银行家算法的返回值int Request[5]={0,0,0,0,0}; //申请的资源量数组int sourcenum=0; //申请的各资源量/*判断系统中进程是否全部运行完毕*/step1: if(Isprocessallover()==1){puts("系统中全部进程运行完毕!");return 0;}/*显示系统当前状态*/Systemstatus();/*人机交互界面*/step2: printf("输入发出请求的进程(输入“0”退出系统):"); scanf("%d",&process);if(process == 0){printf("放弃申请,退出系统!");return 0;}if(process<1 || process>5 ||over[process-1]==1){puts("系统无此进程!");goto step2;}puts("此进程申请各资源(A,B,C,D,E)数目: ");for(i=0;i<5;i++){printf("%c资源:",65+i);scanf("%d",&sourcenum);Request[i] = sourcenum;}/*用银行家算法判断是否能够进行分配*/decide=Banker(process,Request);if (decide==0){/*将此进程申请资源分配给它*/Allow(process,Request);goto step1;}else{/*不能分配,显示原因*/Forbidenseason(decide);goto step2;}return 0;}int Isprocessallover(){int i,j;int processnum=0;for(i=0;i<6;i++){//判断每个进程是否运行完毕if(over[i]==1) processnum++;}if(processnum == 5) return 1; //系统中全部进程运行完毕return 0;}void Systemstatus(){int i,j;puts("此刻系统中存在的进程:");for(i=0;i<5;i++)if(over[i]!=1) printf("P%d ",i+1);puts("");puts("此刻系统可利用资源(单位:个):");puts("A B C D E");for(i=0;i<5;i++) printf("%d ",Availiable[i]);puts("");puts("此刻各进程已占有资源如下(单位:个):");puts(" A B C D E");for(i=0;i<5;i++){if(over[i]==1) continue;printf("P%d ",i+1);for(j=0;j<5;j++) printf("%d ",Allocation[i][j]);puts("");}puts("各进程运行完毕还需各资源如下(单位:个):"); puts(" A B C D E");for(i=0;i<6;i++)if(over[i]==1) continue;printf("P%d ",i+1);for(j=0;j<5;j++) printf("%d ",Need[i][j]); puts("");}}int Banker(int p,int *R){int i,j,m,n;int num=0;int Finish[5]={0,0,0,0,0};int work[5]={0,0,0,0,0};int AvailiableTest[5];int AllocationTest[5][5];int NeedTest[5][5];/*判断申请的资源是否大于系统可提供的资源总量*/for(i=0;i<5;i++){if(*(R+i)>Availiable[i]) return 1;}/*判断该进程申请资源量是否大于初始时其申明的需求量*/for(i=0;i<5;i++){if(*(R+i)>Need[p-1][i]) return 2;}/*为检查分配的各数据结构赋初值*/for(i=0;i<5;i++)AvailiableTest[i]=Availiable[i];for(i=0;i<6;i++)for(j=0;j<5;j++)AllocationTest[i][j] = Allocation[j][i];for(i=0;i<6;i++)for(j=0;j<5;j++)NeedTest[i][j]=Need[j][i];/*进行试分配*/for(i=0;i<5;i++)AvailiableTest[i]-=*(R+i);AllocationTest[p-1][i]+=*(R+i);NeedTest[p-1][i]-=*(R+i);}/*检测进程申请得到满足后,系统是否处于安全状态*/for(i=0;i<5;i++)work[i]=AvailiableTest[i];for(m=1;m<=6;m++){for(n=0;n<6;n++){num = 0;/*寻找用此刻系统中没有运行完的进程*/if(Finish[n]==0&&over[n]!=1){for(i=0;i<4;i++)if(NeedTest[n][i]<=work[i])num++;if(num==4){for(i=0;i<4;i++)work[i]=work[i]+AllocationTest[n][i];Finish[n]=1;}}}}for(i=0;i<6;i++)if(Finish[i]==0 && over[i]!=1)return 3;return 0;}void Allow(int p,int *R){int i,j;puts("可以满足申请!") ;//可以满足申请!static int overnum;/*对进程所需的资源进行分配*/for(i=0;i<5;i++){Availiable[i]=Availiable[i]-*(R+i);Allocation[p-1][i]=Allocation[p-1][i]+*(R+i);Need[p-1][i]=Need[p-1][i]-*(R+i);}/*分配后判断其是否运行完毕*/overnum = 0;for(i=0;i<5;i++)if(Need[p-1][i] == 0) overnum++;if(overnum==5){/*此进程运行完毕,释放其占有的全部资源*/for(i=0;i<5;i++)Availiable[i]=Availiable[i]+Allocation[p-1][i];/*标记该进程运行完毕*/over[p-1]=1;printf("进程 P%d 所需资源全部满足,此进程运行完毕!\n");}}void Forbidenseason(int d){puts("不能满足申请,此进程挂起,原因为:");switch(d){case 1: puts("申请的资源量大于系统可提供的资源量!"); break;case 2: puts("申请的资源中有某种资源大于其声明的需求量!"); break;case 3: puts("若满足申请,系统将进入不安全状态,可能导致死锁!");}}。
银行家算法解决死锁一、实验目的死锁会引起计算机工作僵死,因此操作系统中必须防止。
本实验的目的在于了解死锁产生的条件和原因,并采用银行家算法有效地防止死锁的发生。
二、实验设计思路设Request i 是进程Pi 的请求向量。
Request i (j)=k表示进程Pi请求分配Rj类资源k个。
当Pi发出资源请求后,系统按下述步骤进行检查:1、如果Request i ≤Need,则转向步骤2;否则,认为出错,因为它所请求的资源数已超过它当前的最大需求量。
2、如果Request i ≤Available,则转向步骤3;否则,表示系统中尚无足够的资源满足Pi的申请,Pi必须等待。
3、系统试探性地把资源分配给进程Pi,并修改下面数据结构中的数值:Available = Available - Request iAllocation i= Allocation i+ Request iNeed i= Need i - Request i4、系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。
如果安全才正式将资源分配给进程Pi,以完成本次分配;否则,将试探分配作废,恢复原来的资源分配状态,让进程Pi等待。
三、运行结果1、在程序运行中,程序中已经输入初值:int MaxAvailable[m]={10,5,7}; //每类资源的个数int Max[n][m]={1,5,3,3,2,4,1,0,2,2,2,2,0,3,2};// 每个进程需要的每类资源最大需求个数int Allocation[n][m]={0,1,0,1,0,0,3,0,2,2,1,1,0,0,2};// 已分配给每个进程的每类资源个数int Available[m];int Need[n][m]; //每个进程还需要的每类资源数经过银行家算法和安全性算法,输出运行成功的进程号。
2、在调整输入初值后:int MaxAvailable[m]={10,5,7};int Max[n][m]={7,5,3,3,2,2,9,0,2,2,2,2,4,3,9};int Allocation[n][m]={0,1,0,2,0,0,3,0,2,2,1,1,0,0,2};int Available[m];int Need[n][m];运行结果为三、源代码:#include <iostream>#include <cstdlib>using namespace std;const int m=3; //资源类数const int n=5; //进程个数int MaxAvailable[m]={10,5,7}; //每类资源的个数int Max[n][m]={1,5,3,3,2,4,1,0,2,2,2,2,0,3,2};// 每个进程需要的每类资源最大需求个数int Allocation[n][m]={0,1,0,1,0,0,3,0,2,2,1,1,0,0,2};// 已分配给每个进程的每类资源个数int Available[m];int Need[n][m]; //每个进程还需要的每类资源数struct Request{int p; //进程int k[m]; //请求资源};bool safe() //安全性算法,判断是否安全{int Work[m]; //系统可分配资源for(int i=0;i<m;i++){Work[i]=Available[i];}bool Finish[n]; //运行结束否for(i=0;i<n;i++)Finish[i]=false;for(int iy=0;iy<n;iy++){for(i=0;i<n;i++){if(!Finish[i]){for(int j=0;j<m;j++){if(Need[i][j]>Work[j]) //需求大于系统资源数,跳出{break;}}if(j==m) //m个资源都满足所需{for(int ix=0;ix<m;ix++){Work[ix]+=Allocation[i][ix];}Finish[i]=true;cout<< "[ " <<i << "] \n" << " --> ";break;}}}}for(i=0;i<n;i++){if(!Finish[i])break;}if(i<n) //存在危险{cout<< "危险" <<endl;return false;}elsereturn true;}void bank(Request r) //银行家算法{int i;int j;for(i=0;i<n;i++)for(j=0;j<m;j++){Need[i][j]=Max[i][j]-Allocation[i][j];} //进程需求资源矩阵for(i=0;i<m;i++){Available[i]=MaxAvailable[i];}for(i=0;i<n;i++)for(j=0;j<m;j++){Available[j]-=Allocation[i][j];}for(i=0;i<m;i++){if(r.k[i]>Need[r.p][i]) //如果请求>所需,跳出{break;}}if(i <m){cout<< "Your request over need! " <<endl;exit(1);}else{for(i=0;i<m;i++){if(r.k[i]> Available[i]) //请求>可以使用的break;}if(i<m){cout<< "Process[ " <<r.p << "] Wait! " <<endl;} //等待else //尝试分配{for(i=0;i<m;i++){Available[i]-=r.k[i];Allocation[r.p][i]+=r.k[i];Need[r.p][i]-=r.k[i];}if(!safe()) //判断分配是否安全,如果不安全,撤销分配{for(i=0;i<m;i++){Available[i]+=r.k[i];Allocation[r.p][i]-=r.k[i];Need[r.p][i]+=r.k[i];}cout<< "系统处于不安全状态" <<endl;}else //如果安全,分配成功{cout << "系统处于安全状态" <<endl;}}}}void main(){Request r;r.p=1; //默认资源标记为1int request[m]={1,0,2}; //默认请求资源for(int i=0;i<m;i++){r.k[i]=request[i];}bank(r);}。
模拟通过银行家算法避免死锁一、银行家算法产生的背景及目的1:在多道程序系统中,虽然借助于多个进程的并发执行来改善系统的利用率,提高系统的吞吐量,但可能发生一种危险—死锁。
死锁就是多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵局状态时,如无外力作用,他们将无法再向前进行,如再把信号量作为同步工具时,多个Wait和Signal 操作顺序不当,会产生进程死锁。
然而产生死锁的必要条件有互斥条件,请求和保持条件,不剥夺条件和环路等待条件。
在预防死锁的几种方法中,都施加了较强的限制条件,在避免死锁的方法中,所施加的条件较弱,有可能获得令人满意的系统性能。
在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统都处于安全状态,便可避免死锁。
2:实验目的:让学生独立的使用编程语言编写和调试一个系统分配资源的简单模拟程序,了解死锁产生的原因及条件。
采用银行家算法及时避免死锁的产生,进一步理解课堂上老师讲的相关知识点。
银行家算法是从当前状态出发,逐个按安全序列检查各客户中谁能完成其工作,然后假定其完成工作且归还全部贷款,再进而检查下一个能完成工作的客户。
如果所有客户都能完成工作,则找到一个安全序列,银行家才是安全的。
二:银行家算法中的数据结构1:可利用资源向量Available。
这是一个含有m个元素的数组,其中的每个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态的改变。
如果Available[j]=k,z 则表示系统中现有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个。
模拟通过银行家算法避免死锁一、银行家算法产生的背景及目的1:在多道程序系统中,虽然借助于多个进程的并发执行来改善系统的利用率,提高系统的吞吐量,但可能发生一种危险—死锁。
死锁就是多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵局状态时,如无外力作用,他们将无法再向前进行,如再把信号量作为同步工具时,多个Wait和Signal 操作顺序不当,会产生进程死锁。
然而产生死锁的必要条件有互斥条件,请求和保持条件,不剥夺条件和环路等待条件。
在预防死锁的几种方法中,都施加了较强的限制条件,在避免死锁的方法中,所施加的条件较弱,有可能获得令人满意的系统性能。
在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统都处于安全状态,便可避免死锁。
2:实验目的:让学生独立的使用编程语言编写和调试一个系统分配资源的简单模拟程序,了解死锁产生的原因及条件。
采用银行家算法及时避免死锁的产生,进一步理解课堂上老师讲的相关知识点。
银行家算法是从当前状态出发,逐个按安全序列检查各客户中谁能完成其工作,然后假定其完成工作且归还全部贷款,再进而检查下一个能完成工作的客户。
如果所有客户都能完成工作,则找到一个安全序列,银行家才是安全的。
二:银行家算法中的数据结构1:可利用资源向量Available。
这是一个含有m个元素的数组,其中的每个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态的改变。
如果Available[j]=k,z 则表示系统中现有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个。
三、银行家算法及安全性算法1:银行家算法设Request[i]是进程Pi的请求向量,若Request[i][j]=k;表示进程需要j类资源k个。
当Pi发出资源请求时,系统按下属步骤进行检查;(1)如果Request[i][j]<=Need[i][j];便转向步骤(2),否则认为出错,因为它所需要的资源数已超过他所宣布的最大值。
(2)如果Request[i][j]<=Available[i][j],便转向步骤(3),否则认为尚无足够资源,进程需等待。
(3)系统试探着把资源分配给进程,并修改下面数据结构的数据Available[i][j]=Available[i][j]-Request[i][j];Allocation[i][j]=Allocation[i][j]+Request[i][j];Need[i][j]=Need[i][j]-Request[i][j];(4)系统执行安全性算法,检查此次资源分配后系统是否处于安全状态。
若安全,才正式将资源分配给进程Pi,已完成此次分配。
否则,将本次的试探分配作废,回复原来的资源分配状态,将进程Pi等待。
2:安全性算法(1)设置两个向量;1:工作向量Work,表示系统可提供给进程运行所需的各类资源数目,它含有m个元素,初始时Work=Available2:Finish ,表示系统是否有足够的资源分配给进程,使之运行完成。
开始时先做Finish[i]=true(2)从进程中找到一个能满需下属条件的进程1;Finish[i]=false;2:Need[i][j]<=Work[j];若找到执行步骤(3),否则执行步骤(4)(3)当进程Pi顺利获得资源后,直至完成,并释放分配给它的资源,执行: Work[j]=Work[j]+Allocation[i][j];Finish[i]=true;Go to step (2);(5)如果所有的进程Finish[i]都满足,则表示系统处于安全状态,否则,处于不安全状态。
四、模块设计与分析及整体功能概述模块设计与分析:整个银行家算法分为初始化函数Init(),安全性算法函数 safe(),银行家算法函数bank()三部分。
初始化函数生成开始时刻系统中的进程和资源情况,安全性算法判断当某进程申请资源时,系统能否处于安全状态。
在本实验中,若系统处于安全状态,便生成一个安全进程序列(安全序列可能有多个)。
银行家算法函数bank()负责整体的检查与异常判断。
整体功能概述:死锁会引起系统陷入僵局,操作系统必须防止此现象的发生。
本实验通过一个动态分配资源的模拟程序,更清楚的理解死锁产生的原因和条件。
Dijkstra的银行家算法是最有代表性的避免死锁的方法。
运行程序时用户设定系统中进程和可利用资源的种类数目。
输入各进程的可利用资源Available,最大需求MAX,已分配资源Allocation ,需求资源Need,之后各系统发出资源请求Request,利用实验中的安全性算法判断能否产生一个安全性队列,若能,则给该进程分配成功,否则,不予分配。
五、流程图设计六、源代码及调试分析#include<iostream.h>#define MAXm 50 // 定义最大进程数#define MAXn 100 //定义最大资源数int MAX[MAXm][MAXn]; //最大需求矩阵int Allocation[MAXm][MAXn]; //已分配矩阵int Available[MAXn]; //可用资源数组int Need[MAXm][MAXn]; //需求矩阵int Request[MAXm][MAXn]; //请求矩阵int Finish[MAXm]; //存储完成资源分配的进程int Sequence[MAXm]; //模拟的资源分配序列int Work[MAXn]; //系统是否有足够的资源分配给进程int m,n; //m个进程,n个资源#define False 0#define True 1void input(); //数据输入函数int safealg(); //安全性算法函数void banker(); //银行家算法函数void main(){input();safealg();banker();}//*************初始化算法***************void input(){int i,j;//************自定义进程数目与资源种类*******************cout<<"***********************************\n";cout<<"*利用银行家算法避免死锁*\n";cout<<"* *\n";cout<<"************************************\n";cout<<"请输入进程的数目:";cin>>m;cout<<"请输入资源的种类:";cin>>n;//*****输入每个进程对每种资源的最大需求、已经获得的数量、每种类型资源的数目cout<<"各进程资源最大需求(Max),按照"<<m<<"x"<<n<<"矩阵输入:\n";for(i=0;i<m;i++){cout<<"P"<<i<<":";for(j=0;j<n;j++){cin>>MAX[i][j];if(j==n)cout<<"资源种类数匹配出现错误!";//当资源配置的种类数大于预先输入的数值时,出错}}cout<<"各进程当前获得资源(Allocation),按照"<<m<<"x"<<n<<"矩阵输入"<<endl;for(i=0;i<m;i++){cout<<"P"<<i<<":";for(j=0;j<n;j++){cin>>Allocation[i][j];if(j==n)cout<<"资源种类数匹配出现错误!";//当资源配置的种类数大于预先输入的数值时,出错Need[i][j]=MAX[i][j]-Allocation[i][j];//需求数等于最大需求减去已经分配数}}cout<<"系统可用资源(Available):"<<endl;for(j=0;j<n;j++){cin>>Available[j];//输入各种资源的可利用数}cout<<"当前时刻的进程分配情况如图:\n";cout<<"进程号-"<<"MAX----"<<"Allocation---"<<"Need--"<<"Available---\n";//显示各进程的资源情况for(i=0;i<m;i++){cout<<"P"<<i<<": ";for(j=0;j<n;j++)cout<<" "<<MAX[i][j];for(j=0;j<n;j++)cout<<" "<<Allocation[i][j];cout<<" ";for(j=0;j<n;j++)cout<<" "<<Need[i][j];for(j=0;j<n;j++)cout<<" "<<Available[j];cout<<endl;//回车换行}}//*****************银行家算法,为进程分配资源***********//void banker(){int i,j;int choice;while(1){cout<<endl;cout<<"输入要进行的操作(1:分配资源2:离开) :"; //用户选择cin>>choice;if(choice==1) //分配资源{cout<<"从P0到P"<<m-1<<"之间选择要分配资源的进程号:\n";cin>>i;if(i>=m){cout<<"无此进程号!请重新输入:\n";cin>>i;//重新输入进程号}cout<<"请输入进程申请的资源(Request):"<<endl;for(j=0;j<n;j++)cin>>Request[i][j];//**********银行家算法进行检查*************//for(j=0;j<n;j++){if(Request[i][j]>Need[i][j]){cout<<"申请的资源大于它需要的资源数,请重新输入!\n";//资源申请不合理continue;}if(Request[i][j]>Available[j]){//资源申请数目大于可利用数,无法分配,得等待cout<<"当前系统可用资源不够,请等待!"<<endl;continue;}}for(j=0;j<n;j++)//资源申请得到允许时,变换各个资源数{Available[j]=Available[j]-Request[i][j]; //可用资源减少Allocation[i][j]=Allocation[i][j]+Request[i][j];//所得资源增加Need[i][j]=Need[i][j]-Request[i][j]; //仍需资源减少}if(safealg()<0)//安全性算法的返回值{cout<<"分配不成功,请等待!";for (j=0;j<n;j++) //把资源恢复成分配之前的状态{Available[j]=Available[j]+Request[i][j];Allocation[i][j]=Allocation[i][j]-Request[i][j];Need[i][j]=Need[i][j]+Request[i][j];}for(i=0;i<m;i++){Finish[i]=False;//没有足够的资源分配给该进程}}//if(safealg()<0)else{cout<<"同意分配请求!"<<endl;for(j=0;j<n;j++)Work[j]=Available[j];cout<<"进程号-"<<"--Work----"<<"Need---"<<"Allocation---"<<"Work+Allocation--"<<"Finish--"<<endl;for(i=0;i<m;i++)//按模拟分配序列进行分配{cout<<"进程P"<<Sequence[i]<<": ";for(j=0;j<n;j++)cout<<Work[j]<<" ";cout<<" ";for(j=0;j<n;j++)cout<<Need[Sequence[i]][j]<<" ";cout<<" ";for(j=0;j<n;j++)cout<<Allocation[Sequence[i]][j]<<" ";cout<<" ";for(j=0;j<n;j++)cout<<Allocation[Sequence[i]][j]+Work[j]<<" ";cout<<" ";cout<<Finish[Sequence[i]]<<" ";//完成该进程for(j=0;j<n;j++)Work[j]=Allocation[Sequence[i]][j]+Work[j];//回收该进程所分配的资源cout<<endl;}}//if(safealg()>=0)}//if(choice=1)else if(choice==2) //离开————break;else cout<<"请输入1或2!";//只认可1或2}//while(1)}//*********安全性算法************//int safealg(){int i,j,k,l=0;//int Work[MAXn]; //工作组//记录序列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++)//找到一个满足Finish[i]=false且Need[i][j]<=Work[j]的进程{if(Need[i][j]>Work[j])//由于部分资源得不到满足,进程i无法运行{break;}}if(j==n)//进程各类资源全部得到满足{Finish[i]=True;for(k=0;k<n;k++)//进程i正常运行后,释放其占有的资源{Work[k]+=Allocation[i][k]; //工作分配加上可用资源}Sequence[l++]=i; //模拟资源分配序列生成i=-1; //重新扫描所有进程从i=0开始}else{ //某一资源得不到满足continue; //试探下一个进程}}//if(l==m)//都试探完毕{cout<<"系统安全!"<<endl;cout<<"安全序列:";for(i=0;i<l;i++) //输出安全序列cout<<"进程P"<<Sequence[i]<<"--> ";cout<<endl;return 0;}}//cout<<"系统进入不安全状态!"<<endl;return -1;}分析:输入各进程的可利用资源Available,最大需求MAX,已分配资源Allocation ,需求资源Need,之后各系统发出资源请求Request,利用实验中的安全性算法判断能否产生一个安全性队列,若能,则给该进程分配成功,否则,不予分配。