您的位置:首页 > 其它

【避免死锁的银行家算法】操作系统原理与实践教程实验

2017-05-28 18:00 513 查看
由于滕艳平所写的《操作系统原理与实践教程》这本书的后面的实验在格式上比较乱,且不容易看懂,所以自己在看懂之后写了代码并且在适当的位置后面给予了注释,同时代码的格式更容易看,希望能够更深入了解一下避免死锁的银行家算法。

为了更快读懂代码,推荐步骤如下:

①、理解避免死锁的银行家算法的算法原理

②、由于这篇代码里面也有c++里面的一些东西,如cout<<, cin>>,具体意思在下面的备注里面,在读代码之前应该知道这是什么。

备注:

①什么是cout<<?

简单地说cout就像是c语言中的printf,其中<<后面的内容是输出的内容:

如:cout<<"你好";

就是输出‘你好’。

再比如:cout<<endl<<"p"<<j<<"->allocation:";

其中j是变量,所以不用引号。假设j=1。

输出结果是:先换行,然后输出p1->allocation:

②什么是cin>>?

简单地说cin就是c语言里面的scanf。

如:cin>>k;

就是让你输入变量k的值。

总之这2个东西就是输入输出。但是在使用之前必须加

#include <iostream>
using namespace std ;


滕艳平这本书是
#include <iostream.h>但是运行的时候会报错,即使全部代码打一样也会有报错。

比如:

①、main函数中调用的函数被放在了main函数之后也会报错。

②、滕那本书safecheck函数里面有p[i].state=='W',但是W改成R也对。
如果想深入了解这2个东西,建议查更多详细的资料

/*避免死锁的银行家算法*/
#include <iostream> using namespace std ;
struct PCB{
char state; //进程的状态
int request; //需求量
int max; //最大需求量
int allocation; //当前已经分配给该进程的资源数量
};

/*输出每个进程的编号,最大需求量,当前请求量,已分配量和状态*/
void show(struct PCB p[],int av)
{
int i;
cout<<endl<<"available="<<av;
cout<<endl<<"number max request allocation state";
for(i=0;i<3;i++){ //循环输出每个进程的信息
cout<<endl<<i;
cout<<" ";
cout<<p[i].max;
cout<<" ";
cout<<p[i].request;
cout<<" ";
cout<<p[i].allocation;
cout<<" ";
cout<<p[i].state;
cout<<endl;
}
}
/*随机分配算法*/
void randomallocation(struct PCB p[],int av){
int i=0;
int j=0;
int w;
int e;
while(1) {
if(i==3)
i=i-3;
while(1){
if(i==3)
i=i-3;
else{
if(p[i].state=='R'){ //判断当前进程是不是可以安排资源的状态
do{
cout<<endl<<"p"<<i<<"->request:"; //输入当前进程的需求量
cin>>p[i].request;
}while(p[i].request>(p[i].max-p[i].allocation)); //当输入的需求量不符合条件,执行重新输入
break; //当前进程的资源安排好之后,跳出当前循环
}
else
i++;
}
}
if(p[i].request<=av){ //判断分配的资源是否小于可获得的总资源个数
av=av-p[i].request; //系统剩余资源减少
p[i].allocation=p[i].allocation+p[i].request;
p[i].request=0; //置当前进程的需求量为0
if(p[i].max==p[i].allocation){
av=av+p[i].allocation; //完成该进程,释放该进程所占的资源,归还给系统
p[i].state='E'; //将该进程的状态置为完成状态
p[i].allocation=0;
p[i].request=0;
}
j=0;
while(j<3){
if((p[j].request<=av)&&(p[j].state=='W')){
av=av+p[j].allocation;
p[j].request=0;
p[j].state='E';
p[j].allocation=0;
}
if((p[j].max<av+p[j].allocation)&&(p[j].state=='W')){
p[j].state='R';
}
j++;
}
show(p,av);
}
else{
p[i].state='W';
show(p,av);
}
w=0;
e=0;
for(j=0;j<3;j++){
if(p[j].state=='W')
w++;
else if(p[j].state=='E')
e++;
else break;
}
if(((w+e)==3)&(w!=0)){
cout<<endl<<"发生死锁!";
return;
}
else if(e==3){
cout<<endl<<"三个进程顺利执行完!";
return;
}
i++;
}
}

/*安全性算法*/
bool safecheck(struct PCB p[],int av){
bool finish[3]; //finish有2中取值,true和false,表示该进程是否已经完成
int order[3]; //order里面依次存放已经完成的线程的下标
int i;
int j=0;
int f=0; //f用来存放能够顺利完成的进程的个数
int k=0;
int work; //在试着分配的过程中,work用来等效替代available的作用,表示系统中该资源的剩余量
int temp; //temp用来存放进程的资源拥有量,因为在试分配过程中会改变allocation的值,等试分配完了,用它可以恢复allocation的值
work=av;
for(i=0;i<3;i++) {
order[i]=0;
if(p[i].state=='E') //如果该进程的状态为E,则标志该进程已经完成
finish[i]=true;
else //否则如果该进程的状态不为E,则标志该进程还未完成
finish[i]=false;
}
while(k<3){ //有这个控制的原因:每一次的控制都通过看看所有进程中是否有满足条件的
for(i=0;i<3;i++) {
if((p[i].state=='R')&&(p[i].request<=work)&&(finish[i]==false)){ //试着为该进程分配资源
temp=p[i].allocation;
p[i].allocation=p[i].request+p[i].allocation;
}
if(((p[i].allocation+work)>=p[i].max)&&(finish[i]==false)){
work=p[i].allocation+work; //完成该进程,并且归还该进程使用的资源给系统
finish[i]=true; //标志该进程已经完成
order[j]=i; //将该进程的下标加入已经完成的进程的序列中
j++;
if(p[i].state=='R')
p[i].allocation=temp; //恢复该进程的资源拥有量值
}
}
k++;
}
for(i=0;i<3;i++)
if(finish[i]==true)
f++; // f用来存放能够顺利完成的进程的个数 ,能够顺利完成的个数加1
if(f==3){ //所有进程都能够顺利完成,返回true表示这种分配方式安全
//showorder(order);
return true;
}
else //所有进程不能都顺利完成,返回false表示这种分配方式不安全
return false;
}

/* 银行家算法*/
void bankallocation(struct PCB p[],int av){
int k;
int request;
int f;
int i;
show(p,av);
while(1){
request=0;
k=-1;
do{
if(k!=-1)
cout<<endl<<"不是安全状态!";
av=av+request;
p[k].allocation=p[k].allocation-request;
do{
cout<<endl<<"p"<<"->NO.:";
cin>>k;
}while(p[k].state!='R');
do{
cout<<endl<<"p"<<k<<"->request:";
cin>>request;
}while(request>(p[k].max-p[k].allocation));
if(request>av){
p[k].request=request;
p[k].state='W';
break;
}
p[k].allocation=p[k].allocation+request;
av=av-request;
}while(safecheck(p,av)!=true);
if(p[k].allocation==p[k].max){
p[k].state='E';
av=av+p[k].allocation;
p[k].allocation=0;
}
for(i=0;i<3;i++){
if((p[i].state=='W')&&(p[i].request<=av)){
if(safecheck(p,av)==true){
p[i].allocation=p[i].request+p[i].allocation;
av=av-p[i].request;
p[i].request=0;
p[i].state='R';
if(p[i].max==p[i].allocation){
p[i].state='E';
av=av+p[i].allocation;
p[i].allocation=0;
}
}
else{
cout<<endl<<"不是安全状态!原请求资源量无效。";
p[i].request=0;
p[i].state='R';
}
}
}
show(p,av);
f=0;
for(i=0;i<3;i++){
if(p[i].state=='E')
f++;
}
if(f==3){
cout<<endl<<"所有进程顺利执行完!";
break;
}
}
}
int main()
{
struct PCB process[3]; //定义3个结构体进程
int i; //循环变量,进程号的下标
int j; //循环变量,进程号的下标
int k; //选项变量
int available=10; //可获得的资源
for(i=0;i<3;i++){
cout<<endl; //换行操作
cout<<"p"<<i<<"->max:"; //打印:pi->max ,其中i是变量
cin>>process[i].max; //输入一个进程的资源最大需求量
if(process[i].max>10){ //如果当前进程的需求量大于系统该资源的最大量
cout<<endl;
cout<<"错误,请重新输入!";
i--;
}
else{
do{
cout<<endl<<"->allocation:";
cin>>process[i].allocation;//否则输入当前进程对该资源的拥有量
}
while((process[i].allocation>process[i].max)||(available-process[i].allocation<0)); //当输入的进程的拥有量大于了进程需要的最大量
// 或者大于了系统可提供的最大量,重新执行循环体输入当前进程对该资源的拥有量
available=available-process[i].allocation; //系统中该资源的剩余量(进程对该资源可获得的量)减少
process[i].request=0; // 置该进程的资源需求量为0
process[i].state='R'; //置该进程的状态为R
}
}
show(process,available);
cout<<endl<<"1--随机分配算法 2--银行家算法";
do{
cout<<endl<<"请选择:";
cin>>i;
} while(!((i==1)||(i==2)));
if(i==1){
randomallocation(process,available);
}
else{
do{
if(safecheck(process,available)==false){
cout<<endl<<"当前状态不安全!";
cout<<endl<<" 1--退出 2--重置";
do{
cout<<endl<<"选择:";
cin>>k;
}while((k!=1)&&(k!=2));
if(k==2){ //执行重置
available=10; //置系统资源为10
for(j=0;j<3;j++){ //依次对3个进程执行重置资源拥有量
cout<<endl<<"p"<<j<<"->allocation:";
cin>>process[j].allocation; //输入当前资源的拥有量
available=available-process[j].allocation; //系统资源量减少(减去刚刚分配的)
}
}
}
else{ //安全性检查结果为安全
k=0;
break;
}
}while(k==2);
if(k==1) return -1;
else if(k==0) //如果安全性检查结果为安全,执行银行家算法
bankallocation(process,available);
}
}


运行结果:










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