您的位置:首页 > 其它

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

2017-02-17 21:18 585 查看
首先声明,以下代码参考了这位大牛

但是这位大牛直接给出的代码,其中算法进行了优化也没有比较好的解释,这里我分析了好多时间。

程序主要就是进程模拟和算法实现,比较容易理解。

接着是对银行家算法优化的说明:(直接粘贴自己实验报告上的)

安全性算法:满足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 10

using 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;

//last
Available.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;
}


再附上一组测试数据:

      Max
Allocation 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

调试结果部分示例:





内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  操作系统 算法 优化