操作系统课程设计银行家算法第一章引言1.1 课程设计目地:操作系统是计算机系统的核心系统软件,它负责控制和管理整个系统的资源并组织用户协调使用这些资源,使计算机高效的工作。
课程设计的目的是综合应用学生所学知识,通过实验环节,加深学生对操作系统基本原理和工作过程的理解,提高学生独立分析问题、解决问题的能力,增强学生的动手能力。
第二章银行家算法描述2.1 银行家算法简介:银行家算法是一种最有代表性的避免死锁的算法。
在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。
要解释银行家算法,必须先解释操作系统安全状态和不安全状态。
安全状态:如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。
安全状态一定是没有死锁发生。
不安全状态:不存在一个安全序列。
不安全状态不一定导致死锁。
那么什么是安全序列呢?安全序列:一个进程序列{P1,…,Pn}是安全的,如果对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj (j <i )当前占有资源量之和。
2.2 银行家算法描述:我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。
当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过了该进程对资源的最大需求量。
若超过则拒绝分配资源,若没有超过则再测试系统现存的资源能否满足该进程尚需的最大资源量,若能满足则按当前的申请量分配资源,否则也要推迟分配。
2.3银行家算法原理2.3.1银行家算法的思路先对用户提出的请求进行合法性检查,即检查请求的是不大于需要的,是否不大于可利用的。
若请求合法,则进行试分配。
最后对试分配后的状态调用安全性检查算法进行安全性检查。
若安全,则分配,否则,不分配,恢复原来状态,拒绝申请。
2.3.2 银行家算法中用到的主要数据结构可利用资源向量 int Available[j] j为资源的种类。
最大需求矩阵 int Max[i][j] i为进程的数量。
分配矩阵 int Allocation[i][j]需求矩阵 int need[i][j]= Max[i][j]- Allocation[i][j]申请各类资源数量 int Request i[j] i进程申请j资源的数量工作向量 int Work[x] int Finish[y]2.3.3 银行家算法bank()进程i发出请求申请k个j资源,Request i[j]=k(1)检查申请量是否不大于需求量:Request i[j]<=need[i,j],若条件不符重新输入,不允许申请大于需求量。
(2)检查申请量是否小于系统中的可利用资源数量:Request i[j]<=available[i,j],若条件不符就申请失败,阻塞该进程,用goto语句跳转到重新申请资源。
(3)若以上两个条件都满足,则系统试探着将资源分配给申请的进程,并修改下面数据结构中的数值:Available[i,j]= Available[i,j]- Request i[j];Allocation[i][j]= Allocation[i][j]+ Request i[j];need[i][j]= need[i][j]- Request i[j];(4)试分配后,执行安全性检查,调用safe()函数检查此次资源分配后系统是否处于安全状态。
若安全,才正式将资源分配给进程;否则本次试探分配作废,恢复原来的资源分配状态,让该进程等待。
(5)用do{…}while 循环语句实现输入字符y/n判断是否继续进行资源申请。
2.3.4安全性检查算法(safe()函数)(1)设置两个向量:工作向量Work,它表示系统可提供给进程继续运行所需的各类资源数目,在执行安全性算法开始时,Work= Available。
Finish,它表示系统是否有足够的资源分配给进程,使之运行完成。
开始时先做Finish[i]=0;当有足够的资源分配给进程时,再令Finish[i]=1。
(2)在进程中查找符合以下条件的进程:条件1:Finish[i]=0;条件2:need[i][j]<=Work[j]若找到,则执行步骤(3)否则,执行步骤(4)(3)当进程获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:Work[j]= Work[j]+ Allocation[i][j];Finish[i]=1;goto step 2;(4)如果所有的Finish[i]=1都满足,则表示系统处于安全状态,否则,处于不安全状态。
第三章银行家算法流程图3.1 系统主要过程流程图3.2银行家算法流程图3.3、安全性算法流程图第四章源程序结构分析4.1 程序结构4.1.1初始化chushihua():用于程序开始进行初始化输入数据:进程数量、资源种类、各种资源可利用数量、各进程的各种资源已分配数量、各进程对各类资源最大需求数等。
4.1.2当前安全性检查safe():用于判断当前状态安全性,根据不同地方的调用提示处理不同。
4.1.2 银行家算法bank():进行银行家算法模拟实现的模块,调用其他各个模块进行银行家算法模拟过程。
4.1.4 显示当前状态show():显示当前资源分配详细情况,包括:各种资源的总数量(all)、系统目前各种资源可用的数量、各进程已经得到的资源数量、各进程还需要的资源量。
4.1.5主程序main()逐个调用初始化、显示状态、安全性检查、银行家算法函数,使程序有序的进行。
4.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;4.3 函数声明void chushihua(); //系统初始化函数void safe(); //安全性算法函数void bank(); //银行家算法函数void show (); //输出当前资源分配情况4.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.1源程序代码:#include <iostream.h>#include <vector>#include <iomanip>using namespace std;#define TRUE 1 //定义 TRUE =1#define FALSE 0 //定义 FLASE=0voidbank(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()*********************************************************/// 下面的是在dos命令下使用的程序void init(){int m; //m资源类数int n; //进程数cout<<"输入资源类数"<<endl;cin>>m;vector<int> Available(m); //动态申请数组Available可用资源向量cout<<"输入各类资源总数:"<<endl;for (int i=0;i<m;i++){cout<<"输入R"<<i<<"类资源总数:";cin>>Available[i];}cout<<"\n输入进程数"<<endl;cin>>n;vector<vector<int> > Max(n, vector<int>(m));{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];}}}cout<<"输入已分配的Allocation"<<endl;vector<vector<int> > Allocation(n, vector<int>(m));vector<vector<int> > Need(n, vector<int>(m));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];}}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()函数}// 下面的是在文件中导入我们所需的信息/*/void init(){int m; //m资源类数int n; //进程数cout<<"输入资源类数"<<endl;cin>>m;vector<int> Available(m); //动态申请数组Available可用资源向量cout<<"输入各类资源总数:"<<endl;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));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));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; }}第六章运行结果6.1初始化结果6.1.1通过文本初始化:测试使用的是文本导入信息6.1.2 安全检验6.1.3 dos命令下的手动输入,我们就不做了第七章课程设计总结操作系统的基本特征是并发与共享。