操作系统课程设计-银行家算法与随机分配算法
来源:互联网 发布:如何用手机注册淘宝店 编辑:程序博客网 时间:2024/05/16 05:53
首先声明,以下代码参考了这位大牛。
但是这位大牛直接给出的代码,其中算法进行了优化也没有比较好的解释,这里我分析了好多时间。
程序主要就是进程模拟和算法实现,比较容易理解。
接着是对银行家算法优化的说明:(直接粘贴自己实验报告上的)
安全性算法:满足available和need的关系后,即满足安全性检查进行请求分配。满足request和need的关系以及request和available的关系后即分配资源。同时增加了就绪、等待、完成等进程状态,均在结构体中定义。
随机算法:基本与安全性算法一样,唯一的不同是安全性检查替换成available>0。
改进算法评估:
普通的安全性算法:
(1)、递交请求;
(2)、利用剩下的Available进行分配,若分配成功,则安全,输出安全序列;否则不安全,回滚,分配失败。
改进的安全性算法:
已知:一旦可以用资源比某进程需求小,那么若是实现该进程的请求,不但该进程无法执行完毕(分配了资源而无法达到目的,实质上是对资源的一种浪费,无法得到已有资源),消耗的资源很大程度上限制了其他进程的执行,从而进入不安全状态而死锁。如果在提出资源请求前就对此进程进行安全性检查,Available不满足Need即跳过该进程并等待,这样就可以避免一些无谓的请求。
优点:(1)、避免了一些无意义的请求,使请求的限制范围更加明确,现实生活中增加了效率;
(2)、相比原始银行家算法取消了资源请求后的一系列安全性检查(须用for查看是否所有资源都完成,其实也是动态分配,耗时较多),大大减少了耗时。
缺点:若请求的一部分资源过少不影响其他进程的执行,改进后的算法会屏蔽,这样其实会使一些原本有效的请求变得无法执行。
综述:银行家算法不管在现实还是避免死锁方面,目的都是查看是否可以找到一个安全序列,使所有进程(用户)满足需求。而次优化出现的缺点并不影响安全序列的结果,只是屏蔽了极少量的无意义操作,换来了算法性能提升以及时间减少,所以我认为次优化是可行的。
程序中可能有些地方还按照自己的口味改了改,不过基本思想都是那个大牛的。
ps:课程设计这种东西切记报告要写好,我报告xjb写了一通报告成绩是中等,总成绩硬是被拖到了良好= =
代码:
#include <iostream>#include <stdio.h>#include <stdlib.h>#define os 10using namespace std;struct REC{ int A; int B; int C;};struct PCB{int Id; //进程号,外部标识符char State; //状态 R就绪 W等待 E完成REC Apply; //当前请求量REC Max; //需求总量REC Need; //还需要资源数量REC Allocation; //已分配量};PCB *pos,*tmp, *pos0;REC System, Available;PCB pcb[3];/*void InitPCB(){ printf("输入系统资源总量:\n"); scanf("%d%d%d", &System.A, &System.B, &System.C);int i = 0, a = 0, b = 0, c = 0;for(pos = pcb; pos < pcb+3; pos++){i++;pos->Id = i;pos->State = 'R';pos->Allocation.A = 0;pos->Allocation.B = 0;pos->Allocation.C = 0;pos->Apply.B = 0;pos->Apply.B = 0;pos->Apply.B = 0;}i = 0;for(pos = pcb; pos < pcb+3; pos++){ printf("输入进程%d最大需求Max\n", ++i); scanf("%d%d%d", &pos->Max.A, &pos->Max.B, &pos->Max.C);while(pos->Max.A>os || pos->Max.B>os || pos->Max.C>os || pos->Max.A<0 || pos->Max.B<0 || pos->Max.C<0){ printf("数据输入有错,请重新输入:\n");scanf("%d%d%d", &pos->Max.A, &pos->Max.B, &pos->Max.C);}printf("输入进程%d已分配量\n", i); scanf("%d%d%d", &pos->Allocation.A, &pos->Allocation.B, &pos->Allocation.C);while(pos->Allocation.A>pos->Max.A || pos->Allocation.B>pos->Max.B || pos->Allocation.C>pos->Max.C || pos->Allocation.A<0 || pos->Allocation.B<0 || pos->Allocation.C<0){ printf("数据输入有错,请重新输入:\n");scanf("%d%d%d", &pos->Allocation.A, &pos->Allocation.B, &pos->Allocation.C);}a+=pos->Allocation.A;b+=pos->Allocation.B;c+=pos->Allocation.C;pos->Need.A = pos->Max.A-pos->Allocation.A;pos->Need.B = pos->Max.B-pos->Allocation.B;pos->Need.C = pos->Max.C-pos->Allocation.C;}Available.A = System.A-a;Available.B = System.B-b;Available.C = System.C-c;}*/void InitPCB(){ // printf("输入系统资源总量:\n"); System.A = 10; System.B = 5; System.C = 7;int i = 0, a = 0, b = 0, c = 0;for(pos = pcb; pos < pcb+3; pos++){i++;pos->Id = i;pos->State = 'R';pos->Allocation.A = 0;pos->Allocation.B = 0;pos->Allocation.C = 0;pos->Apply.B = 0;pos->Apply.B = 0;pos->Apply.B = 0;}i = 0;//初始化第一个pos = pcb;pos->Max.A = 7;pos->Max.B = 5;pos->Max.C = 3;pos->Allocation.A = 0;pos->Allocation.B = 1;pos->Allocation.C = 3;a+=pos->Allocation.A; b+=pos->Allocation.B; c+=pos->Allocation.C; pos->Need.A = pos->Max.A-pos->Allocation.A; pos->Need.B = pos->Max.B-pos->Allocation.B; pos->Need.C = pos->Max.C-pos->Allocation.C; //初始化第二个 pos = pos+1;pos->Max.A = 4;pos->Max.B = 3;pos->Max.C = 3;pos->Allocation.A = 4;pos->Allocation.B = 1;pos->Allocation.C = 1;a+=pos->Allocation.A; b+=pos->Allocation.B; c+=pos->Allocation.C; pos->Need.A = pos->Max.A-pos->Allocation.A; pos->Need.B = pos->Max.B-pos->Allocation.B; pos->Need.C = pos->Max.C-pos->Allocation.C; //初始化第三个 pos = pos+1;pos->Max.A = 3;pos->Max.B = 0;pos->Max.C = 6;pos->Allocation.A = 3;pos->Allocation.B = 0;pos->Allocation.C = 1;a+=pos->Allocation.A; b+=pos->Allocation.B; c+=pos->Allocation.C; pos->Need.A = pos->Max.A-pos->Allocation.A; pos->Need.B = pos->Max.B-pos->Allocation.B; pos->Need.C = pos->Max.C-pos->Allocation.C; //lastAvailable.A = System.A-a;Available.B = System.B-b;Available.C = System.C-c;}void print(){int i = 0;printf("......................................................................\n");printf("\n当前状态: {可利用量:[%d %d %d]}\n\n", Available.A, Available.B, Available.C);printf("进程号 状态 最近申请量 需求总量 已分配 还需求量\n");for(pos0 = pcb; pos0 < pcb+3; pos0++){ printf("%d\t%c [%d %d %d] [%d %d %d] [%d %d %d] [%d %d %d]\n", pos0->Id, pos0->State, pos0->Apply.A, pos0->Apply.B, pos0->Apply.C, pos0->Max.A, pos0->Max.B, pos0->Max.C, pos0->Allocation.A, pos0->Allocation.B, pos0->Allocation.C, pos0->Need.A, pos0->Need.B, pos0->Need.C);}printf("......................................................................\n");}int bank(){ printf("\n***************************银行家算法*************************************\n\n");int i = 0;int ans[3];for(pos = pcb ; ; pos++){ pos->Apply.A = pos->Apply.B = pos->Apply.C = 0;if(pos->State == 'R'){ //系统在进行资源分配之前,应先计算此次资源分配的安全性 //若此次分配不会导致系统进入不安全状态,才可将资源分配给进程 //安全性检查的提前减少了不必要的回滚,不安全的等待if(Available.A<pos->Need.A || Available.B<pos->Need.B || Available.C<pos->Need.C){pos->State = 'W';printf("对%d进程提出的请求会导致进入不安全状态,进程%d等待\n", pos->Id, pos->Id);if(pos == pcb+2) pos = pcb-1;continue;}//安全了再分配 if(pos->Need.A==pos->Max.A && pos->Need.B==pos->Max.B && pos->Need.C==pos->Max.C) printf("输入第%d个进程的资源请求量\n", pos->Id); else printf("输入进程%d还需资源量[%d %d %d]个,将其分配给该进程:\n", pos->Id, pos->Need.A, pos->Need.B, pos->Need.C); scanf("%d%d%d", &pos->Apply.A, &pos->Apply.B, &pos->Apply.C); //不满足条件一 while(pos->Apply.A>pos->Need.A || pos->Apply.B>pos->Need.B || pos->Apply.C>pos->Need.C) { printf("资源请求量大于资源需求总量,重新输入:\n"); scanf("%d%d%d", &pos->Apply.A, &pos->Apply.B, &pos->Apply.C); } //不满足条件二,等待 if(pos->Apply.A>Available.A || pos->Apply.B>Available.B || pos->Apply.C>Available.C) { pos->State = 'W'; printf("可利用资源无法满足该资源请求量,进程%d等待\n", pos->Id); if(pos == pcb+2) pos = pcb-1;continue; } //第一、第二条件满足,分配 pos->Allocation.A = pos->Allocation.A+pos->Apply.A; pos->Allocation.B = pos->Allocation.B+pos->Apply.B; pos->Allocation.C = pos->Allocation.C+pos->Apply.C; pos->Need.A = pos->Max.A-pos->Allocation.A; pos->Need.B = pos->Max.B-pos->Allocation.B; pos->Need.C = pos->Max.C-pos->Allocation.C; Available.A = Available.A-pos->Apply.A; Available.B = Available.B-pos->Apply.B; Available.C = Available.C-pos->Apply.C; printf("分配给进程%d[%d,%d,%d]个资源,还需[%d,%d,%d]个资源.\n", pos->Id, pos->Apply.A, pos->Apply.B, pos->Apply.C, pos->Need.A, pos->Need.B, pos->Need.C); print(); //占有的等于总需求,此进程完成 if(pos->Allocation.A==pos->Max.A && pos->Allocation.B==pos->Max.B && pos->Allocation.C==pos->Max.C) { pos->State = 'E'; Available.A += pos->Allocation.A; Available.B += pos->Allocation.B; Available.C += pos->Allocation.C; pos->Allocation.A = pos->Allocation.B = pos->Allocation.C = 0; printf("进程[%d]已得到全部资源并释放了占有的资源!\n", pos->Id); print(); ans[i] = pos->Id; i++; if(pos == pcb+2) pos = pcb-1; } //所有进程处于完成态,输出安全序列 tmp = pcb; if(tmp->State=='E'&&(tmp+1)->State=='E'&&(tmp+2)->State=='E') { printf("银行家算法分配完毕,系统处于安全状态,安全序列是:%d->%d->%d\n", ans[0], ans[1], ans[2]); print(); return 0; } else { if(pos == pcb+2) pos = pcb-1; continue; } }else if(pos->State == 'W')//等待状态的进程,满足就绪条件的变为就绪或直接跳过{ //如果此时可利用资源满足原本变为等待的进程资源请求,则变为就绪 if(Available.A>pos->Apply.A && Available.A>=0 && Available.B>pos->Apply.B && Available.B>=0 && Available.C>pos->Apply.C && Available.C>=0) { pos->State = 'R'; pos--;//变为就绪了以后须马上为其分配 } else { if(pos == pcb+2) pos = pcb-1; continue; }}}}int random(){ printf("\n***************************随机按序分配算法*************************************\n\n");int i = 0;for(pos = pcb; ; pos++){ pos->Apply.A = pos->Apply.B = pos->Apply.C = 0;if(pos->State == 'R'){ if(Available.A<=0 || Available.B<=0 || Available.C<=0){pos->State = 'W';printf("系统资源量不足暂时不能分配给进程[%d],进程等待\n", pos->Id); tmp = pcb;if(tmp->State=='W' && (tmp+1)->State=='W' && (tmp+2)->State=='W')//进程处于完成态{ printf("随机分配算法产生死锁!\n"); return 0;}if(pos == pcb+2) pos = pcb-1;continue;}if(pos->Need.A==pos->Max.A && pos->Need.B==pos->Max.B && pos->Need.C==pos->Max.C) printf("输入第%d个进程的申请量\n", pos->Id);else printf("输入进程%d还需资源量([%d %d %d]个),将其分配给该进程:\n", pos->Id, pos->Need.A, pos->Need.B, pos->Need.C);scanf("%d%d%d", &pos->Apply.A, &pos->Apply.B, &pos->Apply.C); //不满足条件一 while(pos->Apply.A>pos->Need.A || pos->Apply.B>pos->Need.B || pos->Apply.C>pos->Need.C) { printf("资源请求量大于资源需求总量,重新输入:\n"); scanf("%d%d%d", &pos->Apply.A, &pos->Apply.B, &pos->Apply.C); } //不满足条件二,等待 if(pos->Apply.A>Available.A || pos->Apply.B>Available.B || pos->Apply.C>Available.C) { pos->State = 'W'; printf("可利用资源无法满足该资源请求量,进程%d等待\n", pos->Id); tmp = pcb; //所有进程都为等待,则死锁if(tmp->State=='W' && (tmp+1)->State=='W' && (tmp+2)->State=='W'){ printf("随机分配算法产生死锁!\n"); return 0;} if(pos == pcb+2) pos = pcb-1;continue; } //前两个条件都满足,分配资源 pos->Allocation.A = pos->Allocation.A+pos->Apply.A; pos->Allocation.B = pos->Allocation.B+pos->Apply.B; pos->Allocation.C = pos->Allocation.C+pos->Apply.C; pos->Need.A = pos->Max.A-pos->Allocation.A; pos->Need.B = pos->Max.B-pos->Allocation.B; pos->Need.C = pos->Max.C-pos->Allocation.C; Available.A = Available.A-pos->Apply.A; Available.B = Available.B-pos->Apply.B; Available.C = Available.C-pos->Apply.C; printf("分配给进程%d[%d,%d,%d]个资源,还需[%d,%d,%d]个资源.\n", pos->Id, pos->Apply.A, pos->Apply.B, pos->Apply.C, pos->Need.A, pos->Need.B, pos->Need.C); print(); //占有的等于总需求,此进程完成 if(pos->Allocation.A==pos->Max.A && pos->Allocation.B==pos->Max.B && pos->Allocation.C==pos->Max.C) //占有的等于总需求 { pos->State = 'E'; Available.A += pos->Allocation.A; Available.B += pos->Allocation.B; Available.C += pos->Allocation.C; pos->Allocation.A = pos->Allocation.B = pos->Allocation.C = 0; printf("进程[%d]已得到全部资源并释放了占有的资源!\n", pos->Id); print(); if(pos == pcb+2) pos = pcb-1; } tmp = pcb; if(tmp->State=='E' && (tmp+1)->State=='E' && (tmp+2)->State=='E')//进程处于完成态 { printf("随机分配算法没有产生死锁!\n"); print(); return 0; } else { if(pos == pcb+2) pos = pcb-1; continue; }}else if(pos->State == 'W') //等待状态的进程{ if(Available.A>pos->Apply.A && Available.A>=0 && Available.B>pos->Apply.B && Available.B>=0 && Available.C>pos->Apply.C && Available.C>=0) { pos->State = 'R'; pos--; } else { if(pos == pcb+2) pos = pcb-1; continue; }}}}int main(){ // freopen("in.txt", "r", stdin);int n = 9999;printf(" 资源分配 \n");while(n != 0){ printf(" --------------------------------------------------\n"); printf(" | &*****************************& |\n"); printf(" | * 1、银行家算法 * |\n"); printf(" | * 2、随机分配算法 * |\n"); printf(" | * 0、退出程序 * |\n"); printf(" | &*****************************& |\n"); printf(" --------------------------------------------------\n请选择:\n"); scanf("%d", &n);printf("\n");if(n == 1) { InitPCB(); print(); bank(); } else if(n == 2) { InitPCB(); print(); random(); } else if(n == 0) { printf("感谢使用!\n"); exit(0); } else printf("选择错误,请重新选择!\n");}return 0;}
再附上一组测试数据:
MaxAllocation Need Available
P1 7 5 3 0 1 3 7 4 0 3 3 2
P2 4 3 3 4 1 1 0 2 2
P3 3 0 6 3 0 1 0 0 5
调试结果部分示例:
- 操作系统课程设计-银行家算法与随机分配算法
- 操作系统课程设计:银行家算法与随机分配算法(linux篇)
- 操作系统课程设计银行家算法
- 操作系统课程设计银行家算法
- 银行家算法c++课程设计
- 【OS课程设计四】银行家算法
- 操作系统之死锁概述与银行家算法
- 操作系统之银行家算法
- 操作系统--银行家算法设计
- 操作系统之银行家算法
- 操作系统之银行家算法
- 操作系统 之 银行家算法
- 操作系统之银行家算法
- 操作系统::银行家算法
- 操作系统银行家算法
- 操作系统之银行家算法
- 操作系统 银行家算法
- 操作系统算法 之 银行家算法
- Android Studio 2.2新增布局——ConstraintLayout完全解析
- Servlet综合使用
- Java内存管理:深入Java内存区域
- Java泛型中<? extends E>和<? super E>的区别
- list
- 操作系统课程设计-银行家算法与随机分配算法
- AT24C128 EEPROM的读写
- Struts框架(三)——标签库
- linux与window下git的使用
- ZOJ 2965Accurately Say "CocaCola"!
- json对象和json字符串之间的转化
- [HDU]2848 The Euler function[欧拉函数][水题]
- Leetcode-412. Fizz Buzz
- 如何用photoshop把一张图片分割成几张图片呢?