操作系统课程设计-银行家算法与随机分配算法

来源:互联网 发布:如何用手机注册淘宝店 编辑:程序博客网 时间: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

调试结果部分示例:







0 0
原创粉丝点击