任务3编程序模拟银行家算法.docx
- 文档编号:5062373
- 上传时间:2022-12-12
- 格式:DOCX
- 页数:15
- 大小:38.37KB
任务3编程序模拟银行家算法.docx
《任务3编程序模拟银行家算法.docx》由会员分享,可在线阅读,更多相关《任务3编程序模拟银行家算法.docx(15页珍藏版)》请在冰豆网上搜索。
任务3编程序模拟银行家算法
任务3编程序模拟银行家算法
一、课程设计目的
通过设计和调试银行家算法通用程序,加深对死锁概念和死锁避免方法的了解。
二、课程设计内容
编制银行家算法程序,并检测所给状态的系统安全性。
3、课程设计指导
银行家算法是一种最有代表性的避免死锁的算法。
要解释银行家算法,必须先解释操作系统安全状态和不安全状态。
安全状态:
如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。
安全状态一定是没有死锁发生。
不安全状态:
不存在一个安全序列。
不安全状态不一定导致死锁。
那么什么是安全序列呢?
安全序列:
一个进程序列{P1,…,Pn}是安全的,如果对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj(j
1.银行家算法的思路
先对用户提出的请求进行合法性检查,即检查请求的是不大于需要的,是否不大于可利用的。
若请求合法,则进行试分配。
最后对试分配后的状态调用安全性检查算法进行安全性检查。
若安全,则分配,否则,不分配,恢复原来状态,拒绝申请。
2.银行家算法中的数据结构
(1)可利用资源向量Available。
这是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态地改变。
Available[j]=K,则表示系统中现有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个,方能完成其任务。
上述三个矩阵存在如下关系:
Need[i,j]=Max[i,j]-Allocation[i,j]
3.银行家算法
设Request[i]是进程Pi的请求向量,如果Request[i,j]=K,表示进程需要K个Rj类型的资源。
当Pi发出资源请求后,系统按下述步骤进行检查:
(1)如果Request[i,j]<=Need[i,j],便转向步骤
(2);否则认为出错,因为它所需要的资源数已超过它所宣布的最大值。
(2)如果Request[i,j]<=Available[j],便转向步骤(3);否则,表示尚无足够资源,Pi须等待。
(3)系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:
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];
(4)系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。
若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。
4.安全性算法
系统所执行的安全性算法可描述如下:
(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;
gotostep2;
(4)如果所有进程的Finish[i]=true都满足,则表示系统处于安全状态;否则,系统处于不安全状态。
四、源程序结构分析及代码实现
1.程序结构
程序共有以下五个部分:
(1).初始化chushihua():
用于程序开始进行初始化输入数据:
进程数量、资源种类、各种资源可利用数量、各进程的各种资源已分配数量、各进程对各类资源最大需求数等。
(2).当前安全性检查safe():
用于判断当前状态安全性,根据不同地方的调用提示处理不同。
(3).银行家算法bank():
进行银行家算法模拟实现的模块,调用其他各个模块进行银行家算法模拟过程。
(4).显示当前状态show():
显示当前资源分配详细情况,包括:
各种资源的总数量(all)、系统目前各种资源可用的数量、各进程已经得到的资源数量、各进程还需要的资源量。
(5).主程序main()
逐个调用初始化、显示状态、安全性检查、银行家算法函数,使程序有序的进行。
2.数据结构
程序使用的全局变量:
constintx=10,y=10;//定义常量
intAvailable[x];//各种资源可利用的数量
intAllocation[y][y];//各进程当前已分配的资源数量
intMax[y][y];//各进程对各类资源的最大需求数
intNeed[y][y];//还需求矩阵
intRequest[x];//申请各类资源的数量
intWork[x];//工作向量,表系统可提供给进程运行所需各类资源数量
intFinish[y];//表系统是否有足够的资源分配给进程,0为否,1为是
intp[y];//存储安全序列
inti,j;//全局变量,主要用于循环语句中
intn,m;//n为进程的数量,m为资源种类数
intl=0,counter=0;
3.函数声明
voidchushihua(); //系统初始化函数
voidsafe(); //安全性算法函数
voidbank();//银行家算法函数
voidshow(); //输出当前资源分配情况
4.主函数main()
intmain()
{
cout<<……//显示程序开始提示信息
chushihua();//初始化函数调用
cout< showdata();//输出初始化后的状态 //===判断当前状态的安全性=== safe();//安全性算法函数调用 if(l cout<<"\n当前状态不安全,无法申请,程序退出! ! ! ! ! "< cout< system("pause"); sign();//调用签名函数 return0;//break; } else{ inti;//局部变量 l=0; cout<<"\n安全的状态! ! ! "< cout<<"安全序列为: "; cout< for(i=1;i cout<<"==>>"<<"进程"<<"("< } for(i=0;i cout< } bank();//银行家算法函数调用 return0; } 5.银行家算法程序流程图如图3.1所示,银行家算法所用数据可参考ppt上的例子 2.源程序代码: #include #include #include #include //定义全局变量 constintx=10,y=10;//常量,便于修改 intAvailable[x];//各资源可利用的数量 intAllocation[y][y];//各进程当前已分配的资源数量 intMax[y][y];//各进程对各类资源的最大需求数 intNeed[y][y];//尚需多少资源 intRequest[x];//申请多少资源 intWork[x];//工作向量,表示系统可提供给进程继续运行所需的各类资源数量 intFinish[y];//表示系统是否有足够的资源分配给进程,1为是 intp[y];//存储安全序列 inti,j;//i表示进程,j表示资源 intn,m;//n为进程i的数量,m为资源j种类数 intl=0;//l用来记录有几个进程是Finish[i]=1的,当l=n是说明系统状态是安全的 intcounter=0; //函数声明 voidchushihua();//初始化函数 voidsafe();//安全性算法 voidshow();//函数show,输出当前状态 voidbank();//银行家算法 voidjieshu();//结束函数 voidchushihua() { cout<<"输入进程的数量: ";//从此开始输入有关数据 cin>>n; cout<<"输入资源种类数: "; cin>>m; cout< "< for(j=0;j { cout<<"输入资源"< "; cin>>Available[j];//输入数字的过程... Work[j]=Available[j];//初始化Work[j],它的初始值就是当前可用的资源数 } cout< "< for(i=0;i { for(j=0;j { cout<<"输入进程"< "; cin>>Allocation[i][j]; } cout< Finish[i]=0;//初始化Finish[i] } cout< "< for(i=0;i { for(j=0;j { cout<<"输入进程"< "; cin>>Max[i][j]; if(Max[i][j]>=Allocation[i][j])//若最大需求大于已分配,则计算需求量 Need[i][j]=Max[i][j]-Allocation[i][j]; else Need[i][j]=0;//Max小于已分配的时候,此类资源已足够不需再申请 } cout< } cout< } //安全性算法函数 voidsafe() { l=0; for(i=0;i {//i++ if(Finish[i]==0) {//逐个查找Finish[i]==0的进程条件一 counter=0;//记数器 for(j=0;j { if(Work[j]>=Need[i][j])counter=counter+1;//可用大于需求,记数 } if(counter==m)//i进程的每类资源都符合Work[j]>=Need[i][j]条件二 { p[l]=i;//存储安全序列 Finish[i]=1;//i进程标志为可分配 for(j=0;j Work[j]=Work[j]+Allocation[i][j];//释放资源 l=l+1;//记数,现在有L个进程是安全的,当L=N时说明满足安全序列 i=-1;//从第一个进程开始继续寻找满足条件一二的进程 } } } } //显示当前状态函数 voidshow()//函数show,输出当前资源分配情况 { inti,j;//局部变量 intAll[y];//各种资源的总数量 intL1;//局部变量L1 cout<<"当前的状态为: "< cout<<"各种资源的总数量: "< for(j=0;j { cout<<"资源"< "; All[j]=Available[j];//总数量=可用的+已分配的 for(i=0;i cout< } cout< "< for(j=0;j cout<<"资源"< "< cout< "< for(i=0;i<=m;i++) { for(j=i;j cout< for(L1=0;L1 { cout<<"进程"< "; for(j=i;j cout< } } cout< "< for(i=0;i<=m;i++) { for(j=i;j cout< for(L1=0;L1 { cout<<"进程"< "; for(j=i;j cout< } } } //银行家算法函数 voidbank() { cout< "< intk=0;//用于输入进程编号 boolr=false;//初值为假,输入Y继续申请则置为真 do{//输入请求 cout<<"输入申请资源的进程(0-"< "; cin>>k; cout< while(k>n-1)//输入错误处理 { cout< "< cout< "; cin>>k; cout< } cout< "< for(j=0;j { do{//do……while循环判断申请输入的情况 cout<<"进程"< "; cin>>Request[j]; cout< if(Request[j]>Need[k][j]){//申请大于需求量时出错,提示重新输入(贷款数目不允许超过需求数目) cout<<"申请大于需要量! "< cout<<"申请的资源"< "< cout<<"重新输入! "< } else//先判断是否申请大于需求量,再判断是否申请大于可利用量 if(Request[j]>Available[j]){//申请大于可利用量,应该阻塞等待? ……? ? ? cout<<"\n没有那么多资源,目前可利用资源"< "< Finish[k]=0;//该进程等待 gotoppp;//goto语句跳转,结束本次申请 } }while(Request[j]>Need[k][j]);//Request[j]>Available[j]|| } //改变Avilable、Allocation、Need的值 for(j=0;j Available[j]=Available[j]-Request[j]; Allocation[k][j]=Allocation[k][j]+Request[j]; Need[k][j]=Need[k][j]-Request[j]; Work[j]=Available[j]; } //判断当前状态的安全性 safe();//调用安全性算法函数 if(l { l=0; cout<<"\n试分配后,状态不安全,所以不予分配! 恢复原状态"< //恢复数据 for(j=0;j { Available[j]=Available[j]+Request[j]; Allocation[k][j]=Allocation[k][j]-Request[j]; Need[k][j]=Need[k][j]+Request[j]; Work[j]=Available[j]; } for(i=0;i Finish[i]=0;//进程置为未分配状态 } else { l=0; cout<<"\n申请资源成功! ! ! "< for(j=0;j { if(Need[k][j]==0); else{//有一种资源还没全部申请到,则该进程不可执行,不能释放拥有的资源 l=1;//置l为1,作为判断标志 break; } } if(l! =1){//进程可以执行,则释放该进程的所有资源 for(j=0;j Available[j]=Available[j]+Allocation[k][j]; Allocation[k][j]=0; } cout<<"该进程已得到所有需求资源,执行后将释放其所有拥有资源! "< } l=0;//归零 cout<<"\n安全的状态! "< cout<<"安全序列为: "; cout< Finish[0]=0; for(i=1;i cout<<"==>>"<<"进程"<<"("< Finish[i]=0;//所有进程置为未分配状态 } cout< } show();//显示当前状态 ppp: //申请大于可利用量,应该阻塞等待,结束本次资源申请,GOTO语句跳转至此 cout< "; char*b=newchar;//输入y/n,判断是否继续申请< cin>>b; cout< cout<<"-------------------------------------------"< cout< if(*b=='y'||*b=='Y') r=true; else{ r=false;//输入非Y则令R=false jieshu();//调用结束函数 } }while(r==true); } //结束函数 voidjieshu() { cout< cout<<"\t\t演示计算完毕"< cout< } //主函数 intmain() { cout< chushihua();//初始化函数调用 cout< show();//输出当前状态 safe();//判断当前状态的安全性 if(l { cout<<"\n当前状态不安全,拒绝申请! "< cout< return0; } else { inti;//局部变量 l=0; cout< 安全序列为: "< cout<<"进程"<<"("< for(i=1;i for(i=0;i cout< } bank();//调用银行家算法函数 cout<<"\t\t演示计算完毕"< return0; } 六、课程设计的总结 操作系统的基本特征是并发与共享。 系统允许多个进程并发执行,并且共享系统的软、硬件资源。 为了最大限度的利用计算机系统的资源,操作系统应采用动态分配的策略,但是这样就容易因资源不足,分配不当而引起“死锁”。 而我本次课程设计就是得用银行家算法来避免“死锁”。 银行家算法就是一个分配资源的过程,使分配的序列不会产生死锁。 此算法的中心思想是: 按该法分配资源时,每次分配后总存在着一个进程,如果让它单独运行下去,必然可以获得它所需要的全部资源,也就是说,它能结束,而它结束后可以归还这类资源以满足其他申请者的需要。 本次程序就是按照上面的思路展开的。 但是因为时间上的仓促,本课程设计的存在着以下不足: 一、不能实现并发操作,即当总资源同时满足几个进程所需要的资源数时,这些进程不能同时进行,只能一一按进程顺序执行。 二、扫描进程顺序单一,只能按进程到来的顺
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 任务3 编程序模拟银行家算法 任务 程序 模拟 银行家 算法