武汉轻工大学
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
武汉轻工大学
数学与计算机学院
计算机系统与系统软件
课程设计说明书
题目:模拟实现银行家算法实现死锁避免专业:信息管理和信息系统
班级:信管1202 学号: 1205020225 姓名:夏蒙
指导老师:欧阳峥峥
2014年9 月10 日
一.目的和要求
在熟练掌握死锁发生原理和解决死锁问题的基础上,利用一种程序设计语言模拟实现利用银行家算法实现死锁避免,一方面加深对原理的理解,另一方面提高学生通过编程根据已有原理解决实际问题的能力,为学生将来进行系统软件开发和针对实际问题提出高效的软件解决方案打下基础。
二.设计内容
模拟实现银行家算法实现死锁避免。
三.设计环境
Windows操作系统、VC++6.0
C语言
四.设计提示
模拟实现银行家算法对系统资源进行分配,以防止死锁的出现。
本课题肯定不可能实现对实际操作系统的资源管理,而是通过对模拟资源数据的处理,检测银行家算法在防止死锁出现的作用。
银行家算法描述:
第一部分:银行家算法(扫描)
1.如果Request<=Need,则转向2;否则,出错
2.如果Request<=Available,则转向3,否则等待
3.系统试探分配请求的资源给进程
4.系统执行安全性算法
第二部分:安全性算法
1.设置两个向量
(1).工作向量:Work=Available(表示系统可提供给进程继续运行所需要的
各类资源数目)
(2).Finish:表示系统是否有足够资源分配给进程(True:有;False:没有).
初始化为False
2.若Finish[i]=False&&Need<=Work,则执行3;否则执行4(i为资源类别)
3.进程P获得第i类资源,则顺利执行直至完成,并释放资源:
Work=Work+Allocation;
Finish[i]=true;
转2
请充分理解以上银行家算法描述的核心思想。
(详细银行家算法描述见p95)本课题的设计思路:
●需根据教材上银行家算法的描述定义一些模拟数据:
系统中资源的种数(假设:n);
每类资源的数量(假设:m1,m2,…,m n);
当前系统中资源的使用情况等。
●设计方法:
通过静态数据,人工输入来完成银行家算法的工作流程。
此方法只需给出一个当前系统资源的使用情况的模拟数据矩阵(该数据可事先保存于磁盘文件,程序执行后从该磁盘文件读入矩阵数据),然后通过用户手工输入下一个进程的资源申请要求的一维向量(控制台输入,此方式可以输入各种资源请求的可能情况,以检测当前的资源申请后是否系统处于安全状态)。
五、源程序结构分析及代码实现
1.程序结构
程序共有以下五个部分:
(1).初始化chushihua():用于程序开始进行初始化输入数据:进程数量、资源种类、各种资源可利用数量、各进程的各种资源已分配数量、各进程对各类资源最大需求数等。
(2).当前安全性检查safe():用于判断当前状态安全性,根据不同地方的调用提示处理不同。
(3).银行家算法bank():进行银行家算法模拟实现的模块,调用其他各个模块
进行银行家算法模拟过程。
(4).显示当前状态show():显示当前资源分配详细情况,包括:各种资源的总数量(all)、系统目前各种资源可用的数量、各进程已经得到的资源数量、各进程还需要的资源量。
(5).主程序main()
逐个调用初始化、显示状态、安全性检查、银行家算法函数,使程序有序的进行。
2.数据结构
程序使用的全局变量:
const int x=10,y=10; //定义常量
int Available[x]; //各种资源可利用的数量
int Allocation[y][y]; //各进程当前已分配的资源数量
int Max[y][y]; //各进程对各类资源的最大需求数
int Need[y][y]; //还需求矩阵
int Request[x]; //申请各类资源的数量
int Work[x]; //工作向量,表系统可提供给进程运行所需各类资源数量
int Finish[y]; //表系统是否有足够的资源分配给进程,0为否,1为是
int p[y]; //存储安全序列
int i,j; //全局变量,主要用于循环语句中
int n,m; //n为进程的数量,m为资源种类数
int l=0,counter=0;
3.函数声明
void chushihua(); //系统初始化函数
void safe(); //安全性算法函数
void bank(); //银行家算法函数
void show (); //输出当前资源分配情况
4.主函数main()
int main()
{
cout<<…… //显示程序开始提示信息
chushihua(); //初始化函数调用
cout<<endl<<endl;
showdata(); //输出初始化后的状态
//===判断当前状态的安全性===
safe(); //安全性算法函数调用
if (l<n){
cout<<"\n当前状态不安全,无法申请,程序退出!!!!!"<<endl; cout<<endl;
system("pause");
sign(); //调用签名函数
return 0; // break;
}
else{
int i; //局部变量
l=0;
cout<<"\n安全的状态!!!"<<endl;
cout<<"安全序列为: ";
cout<<endl<<"进程"<<"("<<p[0]<<")"; //输出安全序列,考虑显示格式,先输出第一个
for (i=1; i<n; i++){
cout<<"==>>"<<"进程"<<"("<<p[i]<<")";
}
for (i=0; i<n; i++) Finish[i]=0; //所有进程置为未分配状态
cout<<endl<<endl;
}
bank(); //银行家算法函数调用
return 0;
}
5. 操作系统银行家算法流程图:
初始化函数chushihua()开始
输入进程的数量
输入资源种类数
输入个资源当前可用资源数
输入各进程当前已分配的资源数
输入各进程对各类资源的最大需求输出提示:输入有误,请重新输入
初始化函数chushihua()
结束,银行家函数
Bank()
提出请求REQUEST[i]
REQUEST[i]<=NEED[i
]
REQUEST[i]<=AVAILA
BLE[[i]
Safe(); Error;
Error;
输出提示:你的请求被拒!
输出提示:同意分配请求
是否进行再次分配
退出程序,银行家算法Bank()结束; 安全性算法Safe()开始
Work=AVAILABLE;
FINISH=false;
NEED[i]<=Work&&FIN
ISH[i]=false;
Work+=ALLOCATION[i];
FINISH[i]=ture;
所有进程的
FINISH=ture;
安全,输出安全序列
Return ture;
安全算法safe()结束输出提示:系统是不安全的
AVAILABLE[i]-=REQUE ST[i];ALLOCATION[i]-=REQU EST[i];
NEED[i]+=REQUEST[i];
2.源程序代码:
#include <iostream.h>
#include <vector>
#include <iomanip>
using namespace std;
#define TRUE 1 //定义 TRUE =1
#define FALSE 0 //定义 FLASE=0
void
bank(vector<int>,vector<vector<int> >,vector<vector<int> >,int ,int ); //声明bank(应行家算法)
int safe(vector<int> Available,vector<vector<int> >
Need,vector<vector<int> > Allocation,int n,int m);//声明safe()安全
性算法
void init();
/*************************************主函数
main()**************************************************************/
void main()
{
init();
int safe(vector<int> Available,vector<vector<int> >
Need,vector<vector<int> > Allocation,int n,int m);
}
/**************************************初始化函数
init()*********************************************************/
void init()
{
int m; //m资源类数
int n; //进程数
cout<<"输入资源类数"<<endl;
cin>>m;
vector<int> Available(m); //动态申请数组Available可用资源向量cout<<"输入各类资源总数:"<<endl;
/**************************************************************** ********/
/* 下面的被刚掉的为在DOS下输入资源向量*/
/*未被刚掉的是从Available.txt文件中读入数据*/
/**************************************************************** ********/
/*/
for (int i=0;i<m;i++)
{
cout<<"输入R"<<i<<"类资源总数:";
cin>>Available[i];
}
//*/
FILE *fp;
fp=fopen("Available.txt","r+");
cout<<"从Available.txt文件中读入数据,并输出"<<endl;
for(int i=0;i<m;i++)
{
fscanf(fp,"%d",&Available[i]);
cout<<Available[i]<<'\t';
}
fclose(fp);
cout<<"\n输入进程数"<<endl;
cin>>n;
vector<vector<int> > Max(n, vector<int>(m));
/**************************************************************** ********/
/* 下面的被刚掉的为在DOS下输入资源向量*/
/*未被刚掉的是从Max.txt文件中读入数据*/
/**************************************************************** ********/
/*
for ( i=0;i<n;i++)
{
cout<<"输入进程"<<i<<"的最大需求向量";
for (int j=0;j<m;j++)
{
cout<<" 输入需要R"<<j<<"类资源的最大数目";
cin>>Max[i][j];
while (Max[i][j]>Available[j])
{
cout<<j<<"类资源最大需求超过该类资源总量,重新输入";
cin>>Max[i][j];
}
}
}//*/
fp=fopen("Max.txt","r+");
cout<<"从Max.txt文件中读入数据,并输出"<<endl;
for(i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
fscanf(fp,"%d",&Max[i][j]);
cout<<Max[i][j]<<" ";
}
cout<<endl;
}
fclose(fp);
cout<<"输入已分配的Allocation"<<endl;
vector<vector<int> > Allocation(n, vector<int>(m));
vector<vector<int> > Need(n, vector<int>(m));
/**************************************************************** ********/
/* 下面的被刚掉的为在DOS下输入资源向量*/
/*未被刚掉的是从Allocation.txt文件中读入数据*/
/**************************************************************** ********/
/*
for ( i=0;i<n;i++)
{
cout<<"输入为进程"<<i<<"的分配向量";
for (int j=0;j<m;j++)
{
cout<<" 输入分配R"<<j<<"类资源的数目";
cin>>Allocation[i][j];
while(Allocation[i][j]>Max[i][j])
{
cout<<j+1<<"类资源最大需求超过该类需求资源总量,重新输入";
cin>>Allocation[i][j];
}
Need[i][j]=Max[i][j]-Allocation[i][j];
Available[j] =Available[j]-Allocation[i][j];
}
}//*/
fp=fopen("Allocation.txt","r+");
cout<<"Allocation.txt从文件中读入数据,并输出"<<endl;
for(i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
fscanf(fp,"%d",&Allocation[i][j]);
Need[i][j]=Max[i][j]-Allocation[i][j]; //在初始化Max时,同时初始化Need数组
Available[j] =Available[j]-Allocation[i][j]; //在初始化Max时,同时修改Available数组
cout<<Allocation[i][j]<<' ';
}
cout<<endl;
}
fclose(fp);
int safe(vector<int> Available,vector<vector<int> >
Need,vector<vector<int> > Allocation,int n,int m);
cout<<"此状态安全!"<<endl;
bank(Available,Need,Allocation,n,m);//调用银行家算法bank()函数
}
/**************************************银行家算法bank()函数
*********************************************************/
void bank(vector<int> Available,vector<vector<int> >
Need,vector<vector<int> > Allocation,int n,int m)
{
vector<int> Request(m);
int all=0;
//定义变量all,如果all==0,表示进程已经运行完,如果all>=1,表示还有进程没有运行完
for (int i=0;i<n;i++)
for(int j=0;j<m;j++)
all +=Need[i][j];
if (0==all)
{
cout<<"所有进程已经运行完,结束"<<endl;
exit(0);
}
int jc;//任选一个进程
char again;
all=0;//重新初始化all,
while (1)
{
while (all==0)
{
all=0;
//如果all==0,表示进程已经运行完,如果all>=1,表示还有进程没有运行完
//循环直至all>0,即找到一个未运行完的进程
cout<<"任选一个进程作为当前进程0--"<<n-1<<endl;
cin>>jc;
for (int j=0;j<m;j++)
{
all += Need[jc][j];
}
if (0==all)
{
cout<<"此进程已经运行,重新输入"<<endl;
}
}
cout<<"输入该进程的请求向量"<<endl;
for (i=0;i<m;i++)
{
cin>>Request[i];
while(Request[i]>Need[jc][i]||Request[i]>Available[i])
{
cout<<"请求向量无法满足"<<endl;
break;
}
}
///////////////////////////////////////////////////////////////// /////////
//系统试探着把资源分配给该进程
///////////////////////////////////////////
for (i=0;i<m;i++)
{
Available[i]=Available[i]-Request[i];
Allocation[jc][i]=Allocation[jc][i]+Request[i];
Need[jc][i]=Need[jc][i]-Request[i];
}
int bb=0;
bb=safe(Available,Need,Allocation,n,m);//调用安全性算法,判断此次资源分配后,系统是否处安全状态
if (1==bb)
{
cout<<"系统成功分配资源"<<endl;
}
else
{
cout<<"系统未能成分配资源,收回预分配资源"<<endl;
for (i=0;i<m;i++)
{
Available[i]=Available[i]+Request[i];
Allocation[jc][i]=Allocation[jc][i]-Request[i];
Need[jc][i]=Need[jc][i]+Request[i];
}
}
cout<<"您还想再次请求分配吗?是请按y/Y,否请按其它键"<<endl;
cin>>again;
if(again=='y'||again=='Y')
{
all=0;
continue;
}
break;
}
}
/**************************************安全性算法safe()函数
*********************************************************/
int safe(vector<int> Available,vector<vector<int> >
Need,vector<vector<int> > Allocation,int n,int m)
{
vector<int> Work(m),Finish(n);//申请工作向量work,finish Work=Available;
vector<int> count(n); //记录安全序列
int len=-1; //记录安全序列的进程个数,如果len==n,即表示所有的finish【i】=true,处于安全状态
for(int i=0;i<m;i++)Finish[i]=FALSE;
for (i=0;i<n;i++)
{
int needed=1;
for (int j=0;j<m;j++)
{
if(Need[i][j]<=Work[j])
{
needed=needed*TRUE;
}
else needed=needed*FALSE;
}
if ((Finish[i]==FALSE)&&needed==1)
{
for (j=0;j<m;j++)
{
Work[j]=Work[j]+Allocation[i][j];
}
Finish[i]=TRUE;
len=len+1;
count[len]=i;
i=-1;
}
}
if (len==n-1)
{
cout<<"系统是安全的"<<endl;
cout<<"安全序列"<<endl;
for (i=0;i<=len;i++)
{
cout<<count[i];
if (i!=len)
{
cout<<"-->";
}
}
cout<<endl;
return TRUE;
}
else
{
cout<<"系统是不安全的"<<endl; return FALSE; }} 运行结果:
1.初始化结果
2.检测系统资源分配是否安全结果:
六、课程设计的总结
操作系统的基本特征是并发与共享。
系统允许多个进程并发执行,并且共享系统的软、硬件资源。
为了最大限度的利用计算机系统的资源,操作系统应采用动态分配的策略,但是这样就容易因资源不足,分配不当而引起“死锁”。
而我本次课程设计就是得用银行家算法来避免“死锁”。
银行家算法就是一个分配资源的过程,使分配的序列不会产生死锁。
此算法的中心思想是:按该法分配资源时,每次分配后总存在着一个进程,如果让它单独运行下去,必然可以获得它所需要的全部资源,也就是说,它能结束,而它结束后可以归还这类资源以满足其他申请者的需要。
本次程序就是按照上面的思路展开的。
但是因为时间上的仓促,本课程设计的存在着以下不足:一、不能实现并发操作,即当总资源同时满足几个进程所需要的资源数时,这些进程不能同时进行,只能一一按进程顺序执行。
二、扫描进程顺序单一,只能按进程到来的顺序(即编号)来扫描,从而产生的安全顺序只能是在这个顺序的基础上产生的,而其实安全顺序是有多个的。
三、对进程数和资源数进行的数量进行了限制,都只能最多有十个。
四、运行程序后,界面较差,进
程数,所需要资源数,已分配资源数,能用资源数,不能一目了然。
这次课程设计时间上虽说仓促点,但是我依然学到了很多的实用性知识。
除了更深的了解这个算法,而且对C语言进行了复习,而且其过程中有很多的知识点都不记得了,所以在此感谢在此过程中帮助过我的老师和同学。
最后的感悟就是:只要你亲自动手,你就能学到知识。