模拟实现银行家算法 4.docx
- 文档编号:30553922
- 上传时间:2023-08-16
- 格式:DOCX
- 页数:29
- 大小:114.22KB
模拟实现银行家算法 4.docx
《模拟实现银行家算法 4.docx》由会员分享,可在线阅读,更多相关《模拟实现银行家算法 4.docx(29页珍藏版)》请在冰豆网上搜索。
模拟实现银行家算法4
模拟实现银行家算法
学院
专业
学号
学生姓名
指导教师姓名
2014年3月15日
目录
1课设简介1
1.1课程设计题目1
1.2课程设计目的1
1.3课程设计内容1
2实验原理分析1
2.1问题描述1
2.2问题分析2
2.3解决方法2
3主要的功能模块3
3.1程序流程图:
3
3.2数据结构3
3.3算法整体设计与调用4
3.4模块设计与时间复杂度分析4
3.5运行结果5
4总结及参考文献6
4.1总结6
4.2参考文献6
5源代码7
1课设简介
1.1课程设计题目
模拟实现银行家算法
1.2课程设计目的
操作系统课程设计是计算机专业重要的教学环节,它为学生提供了一个既动手又动脑,将课本上的理论知识和实际有机的结合起来,独立分析和解决实际问题的机会。
1)进一步巩固和复习操作系统的基础知识。
2)培养学生结构化程序、模块化程序设计的方法和能力。
3)提高学生调试程序的技巧和软件设计的能力。
4)提高学生分析问题、解决问题以及综合利用C语言进行程序设计的能力。
1.3课程设计内容
运用银行家算法,避免死锁的发生。
在确保当前系统安全的前提下推进的。
对进程请求先进行安全性检查,来决定资源分配与否,从而确保系统的安全,有效的避免了死锁的发生。
问题的关键在于安全性算法,即找安全性序列。
2实验原理分析
2.1问题描述
我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
为保证资金的安全,银行家规定:
(1)当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;
(2)顾客可以分歧贷款,但贷款的总数不能超过最大需求量;
(3)当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款;
(4)当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金.
操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。
当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过了该进程对资源的最大需求量。
若超过则拒绝分配资源,若没有超过则再测试系统现存的资源能否满足该进程尚需的最大资源量,若能满足则按当前的申请量分配资源,否则也要推迟分配。
死锁
死锁是进程死锁的简称,是由Dijkstra于1965年研究银行家算法时首先提出来的。
是指多个进程循环等待它方占有的资源而无限期地僵持下去的局面。
很显然,如果没有外力的作用,那麽死锁涉及到的各个进程都将永远处于封锁状态。
它是计算机操作系统乃至并发程序设计中最难处理的问题之一。
实际上,死锁问题不仅在计算机系统中存在,在我们日常生活中它也广泛存在。
在计算机系统中,涉及软件,硬件资源都可能发生死锁。
例如:
系统中只有一台CD-ROM驱动器和一台打印机,某一个进程占有了CD-ROM驱动器,又申请打印机;另一进程占有了打印机,还申请CD-ROM。
结果,两个进程都被阻塞,永远也不能自行解除。
安全性序列
安全序列的的实际意义在于:
系统每次进行资源分配后,如果对于系统中新的资源状况,存在一个安全序列,则至少存在一条确保系统不会进入死锁的路径。
按照该序列,银行家可以实施一个有效的分配过程使得所有客户得到满足
银行家算法的核心在于安全序列的产生。
安全序列正是一种安全的进程推进顺序
2.2问题分析
(1)从键盘输入当前系统的资源信息,包括当前可用资源,每个进程对各类资源的最大需求量,每个进程当前已分配的各个资源量和每个进程尚需要的各个资源量,输出结果显示在DOS界面上;
(2)输入进程请求,按照设计好的安全性算法进行检查,得到结果并输出整个执行过程的相关信息和最终结果(主要包括资源分配表和安全序列)
(3)要求要有各种异常的处理,程序的可控制性和可连续性执行。
包括对进程的存在有无检查,请求向量的不合法检查,试分配失败后的数据恢复和重新接受进程请求等。
2.3解决方法
该算法选用结构化的设计方法,将该系统划为四块,分别是:
(1)主模块,处在整个系统的最高层,负责组织调用其他模块。
(2)初始化模块,负责从键盘读入系统资源和进程状态,并将系统初识资源分配状态打印。
(3)试分配模块,负责处理进程请求,和相应的数据结构的修改,已经特殊情况的处理。
(4)安全性检查,负责试分配后的安全性检查,以及系统不安全时的资源
3主要的功能模块
3.1程序流程图:
3.2数据结构
主要的数据结构及模块有:
typedefstructmy_process
{
intnum;//进程标号
intMax[M];//表示某个进程对某类资源的最大需求
intAllocation[M];//表示某个进程已分配到某类资源的个数
intNeed[M];//表示某个进程尚需要某类资源的个数
structmy_process*next;//指向下一个结点(进程)
}process;
intAvailable[M]={0};//其中每一个数组元素表示当前某类资源的可用数目,初始化为系统所提供的资源的最大数目
intRequest[M]={0};//请求向量
intRecord_work[N][M]={0};//存储当前work[]的值,以便输出
intSafety[N]={0};//存储安全序列,以便后面排序
3.3算法整体设计与调用
主函数voidmain()主要分四大块:
(1)首先需要初始化Init_process(process**head,intm,int*count),存储系统当前状态信息;
(2)调用安全算法Safety_Algorithm,检测当前系统安全状态,若安全则进行下一步,否则打印相关信息,程序退出。
(3)调用试分配函数Attempt_Allocation,进行试分配,若试分配成功,修改相关数据结构,打印当前系统资源分布图,转下一步,否则,打印提示信息,接收其他请求向量。
(4)再次调用安全性算法,检查试分配以后的系统安全性,若安全打印安全性序列和当前系统资源分布图,并进入新一轮的执行。
否则之前的试分配作废,恢复试分配之前的数据结构,输出相关提示信息,接收下一个进程请求
3.4模块设计与时间复杂度分析
3.4.1系统资源初始化函数Init_process
(1)首先读入系统可用资源。
(2)用malloc()函数动态创建进程并且输入相关资源Max[M],Allocation[M],Need[M]。
进程之间以链表组织,输入-1结束初始化。
for(i=0;i { scanf("%d",&node.Need[i]);//初始化资源 } Insret_Tail(head,node);//插入链尾 (*count)++;//资源个数加1 3.4.2安全性算法Safety_Algorithm 找安全序列,其中用到查找当前合法进程的函数process*Reasonable() (1)先初始化相关数据结构 work=(int*)malloc(m*sizeof(int));//当前系统可用资源 finish=(int*)malloc(n*sizeof(int));//标记向量,初始为false,通过安全检查后最为true (2)Reasonable(head,finish,work,m,n)函数,找到当前可执行的进程,执行Alter_Data()修改当前数据结构。 (3)while(count (2) 3.4.3接受进程请求,试分配Attempt_Allocation(head,Request,Available,M); (1)先判断标志flag的值,若为真,则执行Attempt_Allocation函数,该flag是由Safety_Algorithm返回的。 (2)进入Safety_Algorithm函数,首先输入进程号,并检查该进程是否存在,存在则输入它的请求向量,并进行检查。 request[i]<=p->Need[i] request[i]<=avail[i] 若以上两个条件都为真,试分配成功,则执行Alter_Data()函数,修改相关数据结构,否则该进程被阻塞,系统转而接受其他请求 avail[i]=avail[i]-request[i]; p->Allocation[i]=p->Allocation[i]+request[i]; p->Need[i]=p->Need[i]-request[i]; 将结果打印出来。 3.4.4对试分配后的系统,进行安全性检查Safety_Algorithm。 执行过程同4.4.2大致一样,唯一一点在于当找不到安全序列时,将本次试分配作废,恢复该次试分配之前的数据结构。 3.5运行结果 4总结及参考文献 4.1总结 1)银行家算法很好的解决了系统资源分配过程中的进程死锁问题. 2)通过具体的调试运行很多问题得到解决,进一步增强了我们的解决实际问题的动手能力. 4.2参考文献 [1]严蔚敏吴伟民,.数据结构(C语言版),1999,清华大学出版社; [2]汤小丹梁红兵哲凤屏汤子嬴,计算机操作系统(第三版)西安电子科技大学出版社; 5源代码 //银行家算法 #include #include #include #defineM100//系统资源的种类 #defineN100//进程上限 typedefstructmy_process { intnum;//进程标号 intMax[M];//表示某个进程对某类资源的最大需求 intAllocation[M];//表示某个进程已分配到某类资源的个数 intNeed[M];//表示某个进程尚需要某类资源的个数 structmy_process*next; }process; voidInsret_Tail(process**head,processnode)//尾插法建立进程链表 { process*p=(process*)malloc(sizeof(process)); process*last=NULL; memcpy(p,&node,sizeof(process));//动态创建进程结点 p->next=NULL; if(NULL==*head) { *head=p; } else//找表尾 { last=*head; while(last->next! =NULL) { last=last->next; } last->next=p;//插入链尾 } } voidInit_process(process**head,intm,int*count)//初始化系统资源 { inti,j=0; processnode; printf("请初始化一组进程,进程编号从0开始,输入-1结束输入: \n"); do { node.num=j++; printf("请输入第%d个进程信息: \n",node.num); printf("最大需求矩阵: "); scanf("%d",&node.Max[0]); if(node.Max[0]! =-1)//输入-1结束输入 { for(i=1;i { scanf("%d",&node.Max[i]); } printf("分配矩阵: "); for(i=0;i { scanf("%d",&node.Allocation[i]); } printf("需求矩阵: "); for(i=0;i { //scanf("%d",&node.Need[i]); node.Need[i]=node.Max[i]-node.Allocation[i]; printf("%d",node.Need[i]); if(node.Need[i]<0) { printf("输入的需求矩阵有误或者需求大于最大矩阵,处于不安全状态! ! ! ! ! \n"); exit(0); } } printf("\n"); Insret_Tail(head,node);//插入链尾 (*count)++;//进程数加1 } else { break; } } while (1); } voidPrint(process*head,int*avail,intm)//打印初识系统资源 { process*p=NULL; intcount=0; inti,j; charch; p=head; if(NULL==p) { printf("当前无进程! \n"); exit(0); } else { printf("\n|num||Max||Allocation||Need||Available|\n"); printf("\t"); for(i=0;i<4;i++) { ch='A'; for(j=0;j { printf("%4c",ch++); } printf("\t"); } printf("\n"); while(p! =NULL) { count++; printf("%8.2d",p->num); for(j=0;j { printf("%4d",p->Max[j]); } printf("\t"); for(j=0;j { printf("%4d",p->Allocation[j]); } printf("\t"); for(j=0;j { printf("%4d",p->Need[j]); } printf("\t"); if(count==1) { for(j=0;j { printf("%4d",avail[j]); } } printf("\n"); p=p->next; } printf("\n"); } } process*Location(process*head,intpro_num)//进程定位函数,找到当前请求进程在进程链表中的位置,以便后面对其操作 { process*p=NULL; p=head; if(NULL==p) { printf("error! \n");//异常,当前链表为空 returnp; } else { while(p! =NULL) { if(p->num==pro_num) { break; } else { p=p->next; } } if(NULL==p)//无此进程,输入错误 { printf("无此进程! \n"); returnp; } else { returnp; } } } process*Attempt_Allocation(process*head,int*request,int*avail,intm) {//试分配 intnum,i; process*p=NULL; printf("请输入进程编号: \n"); scanf("%d",&num); p=Location(head,num); if(NULL==p) { printf("无此进程! \n"); returnp; } printf("请输入该进程的请求向量: \n"); for(i=0;i { scanf("%d",&request[i]); } for(i=0;i { if(request[i]<=p->Need[i]) { continue; } else { printf("该请求系统不能满足! \n"); returnNULL; } } for(i=0;i { if(request[i]<=avail[i]) { continue; } else { printf("该请求系统不能满足! \n"); returnNULL; } } for(i=0;i { avail[i]=avail[i]-request[i]; p->Allocation[i]=p->Allocation[i]+request[i]; p->Need[i]=p->Need[i]-request[i]; } returnp; } process*Reasonable(process*head,int*finish,int*work,intm,intn)//找当前可执行的进程 { inti=0,j=0,count=0; process*p=NULL; while (1) { if(finish[i]! =-1)//表示该进程未执行安全性检查 { p=Location(head,finish[i]);//定位该进程 if(p! =NULL) { for(j=0;j { if(p->Need[j]>work[j]) { break; } else { continue; } } if(j==m) { returnp; } else { i++;//当前进程检查没有通过,则进行下一个进程的检查 } } } else { i++;//当前进程已经检查过,则进行下一个进程的检查 } if(i==n) { returnNULL;//遍历所有进程都未找到,则跳出返回NULL } } } voidAlter_Data(process*p,int*work,int*finish,intrecord[][M],intm)//修改相关数据结构 { inti; for(i=0;i { record[p->num][i]=work[i]; work[i]=work[i]+p->Allocation[i]; } finish[p->num]=-1;//表示该进程已通过安全性检查 } intSafety_Algorithm(process*head,int*avail,int*safety,intRecord[][M],intm,intn)//安全性算法 { int*work=NULL; int*finish=NULL; process*p=NULL; process*pro=NULL; inti,count=0; work=(int*)malloc(m*sizeof(int));//当前系统可供给进程的各个资源数目 finish=(int*)malloc(n*sizeof(int));//标志数组 p=head; for(i=0;i { work[i]=avail[i]; } i=0; while(p! =NULL) { finish[i]=p->num; p=p->next; i++; } i=0; while(count { pro=Reasonable(head,finish,work,m,n); if(pro! =NULL)//Need[i,j]<=work[j],即当前系统可以满足该进程 { Alter_Data(pro,work,finish,Record,m); count++; safety[i]=pro->num; i++; } else { printf("当前系统处于不安全状态! \n"); break; } } if(count==n) { printf("当前系统处于安全状态,存在一个安全序列: \n"); for(i=0;i { printf("%d,",safety[i]);//打印安全序列 } puts(""); } free(finish); free(work); finish=NULL; work=NULL; if(count==n) { return1;//找到安全序列则返回1 } else { return0;//未找到安全序列则返回0 } } voidReturn_Source(process*p,int*request,int*avail,intm)//若试分配失败,则恢复试分配前的资源状态 { inti; { for(i=0;i { p->Allocation[i]-=r
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 模拟实现银行家算法 模拟 实现 银行家 算法