1、操作系统第七章实验死锁的避免第7章 死锁的避免软件121 1102052019 金凯1.实验题目:用银行家算法实现资源的分配 银行家算法:Dijkstra (1965)提出了一种能够避免死锁的调度算法,称为银行家算法。其基本思想是:系统中的所有进程放入一个进程集合,先把资源试探性地分配给它。然后找出剩余资源能满足最大需求量的进程,进行分配。(来源于教材202页)2.程序中所使用的数据结构及主要符号说明考虑到一个系统有n个进程和m种不同类型的资源,定义以下向量和矩阵数据结构。1.系统中每类资源总数向量 Resource=(R1,R2,Rm)2.系统中当前每类资源可用数向量 Available=(
2、V1,V2,,Vm)3.进程对各类资源的最大需求矩阵(Cij表示进程Pi需要Rj类资源的最大数目)C11 C12 C1m C21 C22 C2mClaim= Cn1 Cn2 Cnm4.系统中当前资源的已分配情况矩阵(Aij表示进程Pi 已分配到Rj 类资源的数目) A11 A12 A1m A21 A22 A2mAllocation= An1 An2 Anm系统安全性定义:在时刻T0系统是安全的,仅当存在一个进程序列P1,P2, ,Pn,对进程Pk(k=1,2, n)满足公式:Cki-Aki=Vi+Aji(j=1.),k=1,2, ,n;i=1,2, ,m此公式为安全序列(参考教材201页)3.
3、程序流程图1、系统主要过程流程图2、银行家算法流程图3、安全性算法流程图4.源程序 本程序在c+编译器cfree上通过测试,vc6.0没有经过测试。说明:这里建立了如教材204-206页上面的一个例子,模拟了5个进程请求资源的情况。具体可以对照教材说明进行查阅。#include using namespace std;void print(int *Max, int *Allocation, int *Need, int *Available,int p,int r) int i, j ,flag=1; cout(进程号 请求的 占用的 C-A:需要的 可用 )endl; coutPi Cla
4、im Allocation Need Availableendlendl;/这是一个表头,下面是英文,上面用汉字说明作用 for(i=0;ip;i+) coutPit; for(j=0;jr;j+) cout*(Max+i*r+j) ; coutt; /制表符,用于排列,无特殊意义 for(j=0;jr;j+) cout*(Allocation+i*r+j) ; coutt; for(j=0;jr;j+) cout*(Need+i*r+j) ; coutt; if(flag=1) for(j=0;jr;j+) cout*(Available+j) ; flag = 0; coutendlend
5、l; bool checkSafe(int *Need,int *Allocation,int *Available,int p,int r) int i=0, j=0, k=0, m=0, count=0, flag1=0, flag2=0; int *list, *Work; / 设置工作向量Work,安全序列list,均用指针来做。数组太麻烦了 bool *Finish; / 完成标志Finish Work = new intr; Finish = new boolp; list = new intp; / 初始化完成标志Finish,默认为false for(i=0;ip;i+) *(
6、Finish+i) = false; / 初始化工作向量Work for(i=0;ir;i+) *(Work+i) = *(Available+i); / 进行安全检查 while(kp) / 判断Finishi是否为true ,且需求向量小于工作向量 flag1 = 0; for(j=0;j*(Work+j) flag1 = 0; break; flag1 = 1; / 若flag1=1 即Finishi为true ,且需求向量小于工作向量,则该进程可以获得资源 if(flag1=1) for(j=0;jr;j+) *(Work+j) += *(Allocation+m*r+j); *(Fi
7、nish+m) = true; *(list+k) = m; count = 0; k+; else count+; if(count=5) break; m+; if(m=5) m=0; / 若所有进程的*(Finish+i)=true,表示系统处于安全状态 for(i=0;ip;i+) if(*(Finish+i)!=true) flag2 = 0; break; else flag2 =1; delete Work; delete Finish; / 若系统处于安全状态,则输出存在的安全序列,否则安全检测算法结束 if(flag2=1) cout存在安全序列:; for(i=0;ip;i
8、+) coutP*(list+i) ; coutendlendl; delete list; return true; else return false; int main() int p=5,r=3; / 进程数为5,资源数为3 / Max为5*3的最大需求矩阵,Available为可利用资源向量, / Allocation为5*3的分配矩阵,Need为5*3的需求矩阵,请求向量Request1 int *Max, *Available, *Allocation, *Need, *Request1; Max = new intp*r; Available = new intr; Alloc
9、ation = new intp*r; Need = new intp*r; Request1 = new intr; / 初始化Max矩阵 / 7 5 3 / 3 2 2 / 9 0 2 / 2 2 2 / 4 3 3 *(Max+0*r+0) = 7;*(Max+0*r+1) = 5;*(Max+0*r+2) = 3; *(Max+1*r+0) = 3;*(Max+1*r+1) = 2;*(Max+1*r+2) = 2; *(Max+2*r+0) = 9;*(Max+2*r+1) = 0;*(Max+2*r+2) = 2; *(Max+3*r+0) = 2;*(Max+3*r+1) = 2
10、;*(Max+3*r+2) = 2; *(Max+4*r+0) = 4;*(Max+4*r+1) = 3;*(Max+4*r+2) = 3; / 初始化Allocation矩阵 / 0 1 0 / 2 0 0 / 3 0 2 / 2 1 1 / 0 0 2 *(Allocation+0*r+0) = 0;*(Allocation+0*r+1) = 1;*(Allocation+0*r+2) = 0; *(Allocation+1*r+0) = 2;*(Allocation+1*r+1) = 0;*(Allocation+1*r+2) = 0; *(Allocation+2*r+0) = 3;*
11、(Allocation+2*r+1) = 0;*(Allocation+2*r+2) = 2; *(Allocation+3*r+0) = 2;*(Allocation+3*r+1) = 1;*(Allocation+3*r+2) = 1; *(Allocation+4*r+0) = 0;*(Allocation+4*r+1) = 0;*(Allocation+4*r+2) = 2; / 初始化可利用资源向量Available / 3 3 2 *(Available+0) = 3; *(Available+1) = 3; *(Available+2) = 2; / 初始化Need矩阵,c-a
12、for(int i=0;ip*r;i+) *(Need+i) = *(Max+i) - *(Allocation+i); / 打印初始化数据 coutT0时刻的系统资源分配情况:endlendl; print(Max, Allocation, Need, Available, p, r); / p1请求资源矩阵为 Request1(1,0,2) *(Request1+0) = 1;*(Request1+1) = 0;*(Request1+2) = 2; coutP1进程的请求向量为: ; for(int j=0;jr;j+) cout*(Request1+j) ; coutendlendl;
13、/ 请求资源数与最大需求资源数进行逐一比较 int flag = 0; for(int i=0;i*(Need+1*r+i) flag = 0; break; else flag = 1; / 若请求资源数小于最大需求资源数,则进行资源分配判断,否则算法结束 if(flag=1) / 请求资源数与剩余资源数进行逐一比较 int flag2 = 0; for(int i=0;i*(Available+i) flag = 0; break; else flag2 = 1; / 若请求资源数小于最大需求资源数,则进行试探分配,否则算法结束 if(flag2=1) / 系统试探着进行资源分配 for(
14、int i=0;ir;i+) *(Available+i) -= *(Request1+i); *(Allocation+1*r+i) += *(Request1+i); *(Need+1*r+i) -= *(Request1+i); / 试探分配完成后,对该状态进行安全检测,若通过检测,则分配, / 否则本次试探分配作废,恢复原来资源分配状态 if(checkSafe(Need,Allocation,Available,p,r) cout分配资源后系统处于安全状态,可进行分配!endlendl; / 打印分配后的数据 cout为进程分配资源后,T1时刻系统资源分配情况:endlendl; p
15、rint(Max, Allocation, Need, Available, p, r);cout ; cout 程序测试 BY:金凯endl; cout ; cout测试结果:符合银行家算法,可以防止死锁endl; else cout分配资源后系统处于不安全状态,系统不分配该资源!endl; / 本次试探分配作废,恢复原来资源分配状态 for(int i=0;ir;i+) *(Available+i) += *(Request1+i); *(Allocation+1*r+i) -= *(Request1+i); *(Need+1*r+i) += *(Request1+i); else cou
16、t请求资源出错,无足够资源可分配!endl; else cout请求资源出错,请求资源数不能大于需求资源数!endl; delete Max; delete Available; delete Allocation; delete Need; delete Request1; return 0;注解:该程序用的数据是教材上面给出的,为证明特殊性我在下面的运行中先输出一次原始数据,然后修改p1的请求资源数,进行了一次无法分配的输出。修改这一段程序:/ p1请求资源矩阵为 Request1(1,0,2) *(Request1+0) = 1;*(Request1+1) = 0;*(Request1+
17、2) = 2;修改为:*(Request1+0) = 2;*(Request1+1) = 0;*(Request1+2) = 2;运行程序后报错:告诉说无法分配!即验证了该程序的有效性。5.心得体会:通过本次实验,我对于银行家算法有了更详尽的认识。死锁避免方法能支持更多的进程并发执行,让在可行的情况下让进程充分利用资源,而是动态的确定是否分配资源给提出请求的进程。在这个算法中如果一个资源的分配会导致下一步死锁,系统便拒绝本次分配。在编程的过程中发现会用到大量的指针,用指针来操作大量的数据比较方便,但最后应该记得释放资源。从这次实验中我发现我对于c+掌握也有所不足,程序经过了多次修改才得以完善,在以后应该注重编程方面的训练。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1