实验二、银行家算法
(一) 目的和要求
银行家算法是由Dijkstra设计的最具有代表性的避免死锁的算法。本实验要求用高级语言编写一个银行家的模拟算法。通过本实验可以对预防死锁和银行家算法有更深刻的认识。
(二) 实验内容
1、 设置数据结构
包括可利用资源向量(Availiable),最大需求矩阵(Max),分配矩阵(Allocation),需求矩阵(Need)
2、 设计安全性算法
设置工作向量Work 表示系统可提供进程继续运行可利用资源数目,Finish 表示系统是否有足够的资源分配给进程
(三) 实验环境
1、 pc
2、 vc++
(四)、程序源代码:
/子函数声明/
int Isprocessallover(); //判断系统中的进程是否全部运行完毕
void Systemstatus(); //显示当前系统中的资源及进程情况
int Banker(int ,int *); //银行家算法
void Allow(int ,int *); //若进程申请不导致死锁,用此函数分配资源
void Forbidenseason(int ); //若发生死锁,则显示原因
/*全局变量*/
int Availiable[3]={3,3,2}; //初始状态,系统可用资源量
int Max[5][3]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
//各进程对各资源的最大需求量
int Allocation[5][3]={{0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2}};
//初始状态,各进程占有资源量
int Need[5][3]={{7,4,3},{1,2,2},{6,0,0},{0,1,1},{4,3,1}};
//初始状态时,各进程运行完毕,还需要的资源量
int over[5]={0,0,0,0,0}; //标记对应进程是否得到所有资源并运行完毕
#include <iostream.h>
/*主函数*/
void main()
{
}
上述为本次实验报告的题目,本文纯原创文章,撰写目的是分享借鉴顺便拿一点原力进行签到。不喜勿喷,有误请指正。
源代码:
#include<iostream>
using namespace std;
/*子函数声明*/
bool Isprocessallover(); //判断系统中的进程是否全部运行完毕(将报告模板的int改成了bool)
void Systemstatus(); //显示当前系统中的资源及进程情况
bool is(int ); //是否满足运行的资源要求
void destroy(); //假设进程运行完毕,释放资源
bool Banker(); //银行家算法
void Allow(int x); //若进程申请不导致死锁,用此函数分配资源
void Forbidenseason(int ); //若发生死锁,则显示原因
/*全局变量*/
int num=0; //表示第几次执行银行家算法
int Availiable[3]={3,3,2}; //初始状态,系统可用资源量
int Max[5][3]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
//各进程对各资源的最大需求量
int Allocation[5][3]={{0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2}};
//初始状态,各进程占有资源量
int Need[5][3]={{7,4,3},{1,2,2},{6,0,0},{0,1,1},{4,3,1}};
//初始状态时,各进程运行完毕,还需要的资源量
int over[5]={0,0,0,0,0}; //标记对应进程是否得到所有资源并运行完毕
bool Isprocessallover(){
for(int i=0;i<5;i++)
if(over[i]==0)
return false;
return true;
}
void Systemstatus(){
cout<<"系统可用资源:{";
for(int i=0;i<3;i++){
cout<<Availiable[i];
if(i!=2) cout<<",";
}
cout<<"}"<<endl<<"各进程对资源的需求量:{";
for(int i=0;i<5;i++){
cout<<"{";
for(int j=0;j<3;j++){
cout<<Max[i][j];
if(j!=2) cout<<",";
}
cout<<"}";
}
cout<<endl<<"各进程对资源的占有量:{";
for(int i=0;i<5;i++){
cout<<"{";
for(int j=0;j<3;j++){
cout<<Allocation[i][j];
if(j!=2) cout<<",";
}
cout<<"}";
}
cout<<"}"<<endl<<"各进程还需要的资源量:{";
for(int i=0;i<5;i++){
cout<<"{";
for(int j=0;j<3;j++){
cout<<Need[i][j];
if(j!=2) cout<<",";
}
cout<<"}";
}
cout<<"}"<<endl;
}
bool is(int x){
for(int i=0;i<3;i++){
if(Need[x][i]>Availiable[i])
return false;
}
return true;
}
void Allow(int x){
cout<<"第"<<x+1<<"个进程获得足够运行的资源量"<<endl;
for(int i=0;i<3;i++){
Availiable[i]-=Need[x][i];
Allocation[x][i]+=Need[x][i];
Need[x][i]=0;
}
}
void Forbidenseason(){
cout<<"进程申请将导致死锁,无程序能获得足够资源量开始运行"<<endl;
}
void destroy(int x){
cout<<endl<<"-----------------进程运行完毕,开始下一轮银行家算法-----------------"<<endl;
for(int i=0;i<3;i++){
Availiable[i]+=Allocation[x][i];
Allocation[x][i]=0;
over[x]=1;
}
}
bool Banker(){
if(Isprocessallover()){
return 1;
}
cout<<endl<<"-----------------银行家算法执行次数:"<<++num<<"-----------------"<<endl;
for(int i=0;i<5;i++){
if(is(i) && over[i]==0){
Allow(i);
Systemstatus();
destroy(i);//假设进程运行完毕,接着释放资源开始下一轮银行家算法调度
Systemstatus();
return Banker();
}
}
Forbidenseason();
return 0;
}
/*主函数*/
int main(){
cout<<endl<<"-----------------初始状态-----------------";
Systemstatus();
if(Banker()==true)
cout<<"程序能通过银行家算法正常执行完毕"<<endl;
return 0;
}
结果截图
实验代码解释:
按照实验题目给出模板(全局变量和部分函数声明)进行代码编写。源代码中的注释已经非常详细。
此实验较实验一更加简单,原始状态直接给出,无需再进行输入处理。为了每个函数代码够简短,更直观,增加了两个函数bool is(int ); void destroy();
程序入口main()首先将初始状态输出,调用了一次Systemstatus()函数。接着调用银行家算法,银行家返回一个整数(bool), 1表示全部调度完,0表示调度失败产生死锁。同样,和实验一类似,需要一个循环结构,此处我使用递归方式来实现循环结构。当然,递归和迭代两种方式最后的结构都一样。每次算法的流程也十分简单,就是循环遍历进程队列,直到出现剩下资源能够满足执行所需资源的进程或者全部资源都不满足才结束。前者正常工作等待该进程执行完毕释放资源,接着继续下一轮银行家算法;后者即表示产生了死锁,调度失败。而产生死锁原因很简单,都是系统所能调配的资源无法满足任一就绪队列进程运行还需的资源数。