您的位置:首页 > 编程语言 > C语言/C++

银行家算法c++课程设计

2017-05-30 22:29 134 查看
课程设计报告名称
 

 

1. 课程设计内容

 本实验实现“银行家算法”

银行家算法的作用是防止发生死锁,提前检测出系统是否安全,如果系统安全,银行家算法还会求出系统的安全序列。银行家算法中银行家对客户相当与系统对进程,系统对进程有一定的约束条件:每个进程必须预先说明所要的最大资源量;可以对操作者提出某进程资源量的申请并判断能否成功,如果系统满足进程对资源的最大需求量,那么进程在资源运行后,应在有限时间内全部归还系统,释放资源。

2. 背景知识

如果一个进程集合中每个进程都在等待只能由此集合中的其他进程才能引发的事件,而无限期陷入僵持的局面称为死锁。

产生死锁的原因主要是: 
(1) 因为系统资源不足。 
(2) 进程运行推进的顺序不合适。 
(3) 资源分配不当等。

银行家算法的安全序列主要是从改变进程运行推进的顺序入手,从而得出安全序列。

3. 设计步骤与方法

3.1. 步骤1:

3.1.1 步骤1:流程图设计

 


 

3.1.2 步骤1:初始化 

本程序设计了两个数据输入的方式,一个是通过文件流读取txt文件,另一个是通过控制台直接输入数据,由此可得到以下几种数据,

m,代表进程的数目;

n,代表进程的资源的种类;

int AVAILABLE[MAXRESOURCE];                    /*可用资源数组*/  

int MAX[MAXPROCESS][MAXRESOURCE];            /*最大需求矩阵*/  

int ALLOCATION[MAXPROCESS][MAXRESOURCE];    /*已有的资源分配矩阵*/  

并由上述的数组之间的关系得到:

int NEED[MAXPROCESS][MAXRESOURCE];            /*需求矩阵*/  

 

3.2. 步骤2:算法

3.2.1. 步骤1:检测安全性算法

设置四个状态

a.设置两个变量

bool FINISH[MAXPROCESS];  //FINISH是否被访问且安全,全true表示系统安全

int Work[MAXRESOURCE];
/*工作数组*/  

使Work[i]=AVAILABLE[i];  

b.由need矩阵中找到一行i,它满足FINISH[i]=false,同时NEED[i]<=Work,转c状态;

如果没有这样的行存在则转;

c.使Work[i]=Work+Alloc[i];且Finsh[i]=true,转b;

d.对于所有的i(i=0,1,2,...,n-1),Finish[i]=true,则系统状态是安全的,否则不安全;

此算法仅用于测试系统的安全性与否,以及输出一种特定的安全序列。

3.2.2系统请求资源算法,调用系统状态安全性算法

 a.REQUEST[i]是当前进程的请求向量,若REQUEST[i]<=NEED[i],则转b,否则给出错误信息“您输入的该线程的资源请求数超过进程的需求量!”请求重新输入或退出

b.若REQUEST[i]>AVAILABLE[i],则转c,否则给出错误信息“您输入的该线程的资源请求数超过系统有的资源数!”请求重新输入或退出

c.假定满足它的资源请求,为其分配资源,并修改系统状态

cusneed为当前请求的线程

AVAILABLE[i]-=REQUEST[cusneed][i];//系统可用资源减去申请了的  

ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];//线程被分配的资源加上已申请了的  

NEED[cusneed][i]-=REQUEST[cusneed][i];//线程还需要的资源减去已申请得到的

d.AVAILABLE  ALLOCATION  NEED变动之后,是否会导致不安全,需要调动上面步骤的安全函数验证,若安全则假分配为真分配,若为不安全则重置。该进程等待 

3.3. 步骤n:输出以及退出函数

bool showdata()   //显示  

int exit(); //退出函数

showdata()函数表示输出的界面以及满足全部资源已分配成功后系统将会自动退出

exit()是在后来添加上去的,在步骤3.2中,可以根据提示提前退出程序。

4.图形界面代码参考了网上某位仁兄的,如下,望各位指点:

#include<iostream>
#include<algorithm>
#include<fstream>
#include <stdlib.h>
#include<string.h>
#include<cstring>
#include<string>
using namespace std;
#define MAXPROCESS 50                        /*最大进程数*/
#define MAXRESOURCE 100                        /*最大资源数*/
int AVAILABLE[MAXRESOURCE];                    /*可用资源数组*/
int MAX[MAXPROCESS][MAXRESOURCE];            /*最大需求矩阵*/
int ALLOCATION[MAXPROCESS][MAXRESOURCE];    /*已有的资源分配矩阵*/
int NEED[MAXPROCESS][MAXRESOURCE];            /*需求矩阵*/
int REQUEST[MAXPROCESS][MAXRESOURCE];        /*进程需要资源数*/
bool FINISH[MAXPROCESS];
int p[MAXPROCESS];                 /*记录序列*/
int m,n,i,j,l,sign=1;                                    /*m个进程,n个资源*/
int visited[MAXPROCESS];     //是否已被访问的标记
void Init();  //初始化函数,包含输入
bool Safe();  //检测系统安全函数
bool Bank();  //系统状态安全性算法
bool showdata();
int exit();
int main()
{
Init();
Safe();
Bank();
return 0;
}
int exit()
{
char again;
cout<<"您还想再次请求分配吗?是请按y/Y,否请按其它键"<<endl;
cin>>again;
if(again=='y'||again=='Y')
{
return 1;
}
else return 0;
}
void Init()                /*初始化算法*/
{
int flag=1;
ifstream infile;
cout<<"请问你想导入txt文件请按0,控制台输入请按1"<<endl;
char str;
cin>>str;
if(str=='0')
{
flag=0;
infile.open("input.txt");
if (!infile){
cout << "不能打开输入文件\n";
cout<<"自动跳转至控制台输入";
flag=1;
}
else
cout<<"已打开输入文件"<<endl;
}
else
{
flag=1;
}
int i,j;
cout<<"请输入进程的数目:\n";
if(flag) cin>>m;
else
{
infile>>m;
cout<<m<<endl;
}
for(i=0;i<m;i++)
{
visited[i]=0;
}
cout<<"请输入资源的种类:\n";
if(flag) cin>>n;
else {
infile>>n;
cout<<n<<endl;
}
cout<<"请输入每个进程最多所需的各资源数,按照"<<m<<"x"<<n<<"矩 阵输入"<<endl;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
if(flag)
cin>>MAX[i][j];
else
infile>>MAX[i][j];
}
}
if(!flag)
{
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
cout<<MAX[i][j]<<" ";
}
cout<<endl;
}
}

cout<<"请输入每个进程已分配的各资源数,也按照"<<m<<"x"<<n<<"矩 阵输入"<<endl;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
if(flag) cin>>ALLOCATION[i][j];
else infile>>ALLOCATION[i][j];
NEED[i][j]=MAX[i][j]-ALLOCATION[i][j];
if(NEED[i][j]<0)
{
cout<<"您输入的第"<<i+1<<"个进程所拥有的第"<<j+1<<"个资源数 错误,请重新输入:"<<endl;
j--;
continue;
}
}
}
if(!flag)
{
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
cout<<ALLOCATION[i][j]<<" ";
}
cout<<endl;
}
}
cout<<"请输入各个资源现有的数目:"<<endl;
for(i=0;i<n;i++)
{
if(flag)
cin>>AVAILABLE[i];
else
{
infile>>AVAILABLE[i];
}
}
if(!flag)
{
for(i=0;i<n;i++)
cout<<AVAILABLE[i]<<" ";
}
cout<<endl;
}
bool Bank()                /*银行家算法*/
{
int i,cusneed,flag = 0;
//if(!Safe())
//	return 0;
while(1)
{
if(showdata())
break;
cout<<endl;
input:
cout<<"请输入要申请资源的进程号(注:第1个进程号为0,依次类推)"<<endl;
cin>>cusneed;
if (cusneed > m-1)
{
cout<<"没有该进程,请重新输入"<<endl;
goto input;
}
if(visited[cusneed])
{
cout<<"该进程已释放资源,请重新输入;"<<endl;
if(exit()) goto input;
else return 0;
}
cout<<"该进程所需要的各资源的数量"<<endl;
for(i=0;i<n;i++)
{
REQUEST[cusneed][i]=MAX[cusneed][i]-ALLOCATION[cusneed][i];
cout<<REQUEST[cusneed][i]<<" ";
}
cout<<endl;
for(i=0;i<n;i++)
{
if(REQUEST[cusneed][i]>NEED[cusneed][i])//如果用户选择的线程的第i个资源请求数>该线程该资源所需的数量
{
cout<<"您输入的该线程的资源请求数超过进程的需求量!"<<endl;
if(!exit()) return 0;
goto input;
}
if(REQUEST[cusneed][i]>AVAILABLE[i])//如果用户选择的线程的第i个资源请求数>系统现有的第i个资源的数量
{
cout<<"您输入的该线程的资源请求数超过系统有的资源数!"<<endl;
if(!exit()) return 0;
goto input;
}
}
for(i=0;i<n;i++)//如果请求合理,那么下面
{
AVAILABLE[i]-=REQUEST[cusneed][i];//系统可用资源减去申请了的
ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];//线程被分配的资源加上已申请了的
NEED[cusneed][i]-=REQUEST[cusneed][i];//线程还需要的资源减去已申请得到的
}
if(Safe())//AVAILABLE  ALLOCATION  NEED变动之后,是否会导致不安全
{
cout<<"同意分配请求!"<<endl;
visited[cusneed]=1;
}
else
{
cout<<"您的请求被拒绝!"<<endl;
for(i=0;i<n;i++)
{
AVAILABLE[i]+=REQUEST[cusneed][i];
ALLOCATION[cusneed][i]-=REQUEST[cusneed][i];
NEED[cusneed][i]+=REQUEST[cusneed][i];
}
}
for (i=0;i<n;i++)
{
if (NEED[cusneed][i] <= 0)
{
flag++;
}
}
if (flag == n)//如果该进程各资源都已满足条件,则释放资源
{
for (i=0;i<n;i++)
{
AVAILABLE[i] += ALLOCATION[cusneed][i];
ALLOCATION[cusneed][i] = 0;
NEED[cusneed][i] = 0;
}
cout<<"线程"<<cusneed<<" 占有的资源被释放!"<<endl;
flag = 0;
}
for(i=0;i<m;i++)//分配好了以后将进程的标识FINISH改成false
{
FINISH[i]=false;
}
if(!exit())
break;
}
return 0;
}
bool Safe()                                    /*安全性算法*/
{
int i,j,k,l=0;
int Work[MAXRESOURCE]; /*工作数组*/
for(i=0;i<n;i++)
Work[i]=AVAILABLE[i];
for(i=0;i<m;i++)
{
FINISH[i]=false;//FINISH表示该线程没满足资源最大需求
}
int f,t=m;
b:
while (t--)
{
for(i=0;i<m;i++)
{
if(FINISH[i]==false)
{
k=0;
for(j=0;j<n;j++)//循环查找第i个进程需要的各个资源数 是否 超过系统现有的对应的资源数
{
if(NEED[i][j]<=Work[j])//第i个进程需要的第j个资源数 <= 系统现有的第j个资源数
k++;
}
if(k==n)//满足进程的资源请求
{
f=i;
goto c;
}
}
}
}
goto d;
c:
FINISH[f]=true;//给该进程的FINISH标记为true,即该进程满足资源最大需求
for(k=0;k<n;k++)
{
Work[k]+=ALLOCATION[f][k];//将Work赋值为 第i个进程各个已分配资源数+系统现有的对应资源数(因为当改进程全部资源数都满足时线程结束并将资源返还给系统)
}
p[l++]=f;//记录进程号
goto b;
d:
for(i=0;i<m;i++)
{
if(FINISH[i]==false)
{
cout<<"系统是不安全的"<<endl;
return 0;
}
}
if(i==m)
{
cout<<"系统是安全的"<<endl;
if(sign)
{
cout<<"存在一种安全序列为:"<<endl;
for(i=0;i<l;i++)
{
cout<<p[i];
if(i!=l-1)
{
cout<<"-->";
}
}
cout<<""<<endl;
sign=0;
}
return 1;
}
}
bool showdata()   //显示
{
int i,j;
cout<<endl;
cout<<"-------------------------------------------------------------"<<endl;
cout<<"系统可用的资源数为:    ";
for   (j=0;j<n;j++)
cout<<"    "<<AVAILABLE[j];
cout<<endl;
cout<<"各进程还需要的资源量:"<<endl;
for   (i=0;i<m;i++)
{
cout<<"    进程"<<i<<":";

for   (j=0;j<n;j++)
cout<<"     "<<NEED[i][j];
cout<<endl;
}
cout<<endl;
int num=0;
for   (i=0;i<m;i++)
{
for   (j=0;j<n;j++)
{
if(ALLOCATION[i][j]==0)
{
num++;
}
}
}
if(num==n*m)
{
cout<<"线程已全部运行完毕,系统将会退出	"<<endl;
system("pause");
return true;
}
else
{
return false;
}
}


这里采用了goto的方法我觉得还是可以的,但是一旦到大型的工程项目的时候就不建议推荐了,还望指教!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ 设计