当前位置:   article > 正文

银行家算法(初学者,简单易懂)

银行家算法

一、背景知识

     银行家算法(Banker's Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行,这种算法的提出能保证银行在发送贷款的时候,不会发生不满足所有用户需要的情况。

二、实验内容

1. 银行家算法中的数据结构

(1)可利用资源向量Available。它含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目,如果Available[j]=K,则表示系统中现有Rj类资源K个。

(2)最大需求矩阵Max。是一个n×m的矩阵,如果Max(i,j)=K,则表示进程i需要Rj 类资源的最大数目为K。

(3)分配矩阵Allocation。是一个n×m的矩阵,如果Allocation(i,j)=K,则表示进程i当前已分得Rj 类资源的数目为K。

(4)需求矩阵Need。是一个n×m的矩阵,如果Need(i,j)=K,则表示进程i还需要Rj 类资源K个,方能完成其任务。

上述三个矩阵间存在下述关系:Need[i,j]=Max[i,j]-Allocation[i,j]

2. 银行家算法

如果Requesti[j]=K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:

(1)如果Requesti[j]<=Need[i,j],转步骤(2);否则出错。

(2)如果Requesti[j]<=Available[j],转步骤(3);否则,表示尚无足够资源,Pi须等待。

(3)系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:

     Available[j]:= Available[j]-Requesti[j];

     Allocation[i,j]:=Allocation[i,j]+ Requesti[j];

     Need[i,j]:=Need[i,j]- Requesti[j];

(4) 系统执行安全性检查,若安全,则正式分配;否则,本次的试探分配作废,恢复原本的资源分配状态,让进程Pi等待。

3. 安全性检查

(1) 设置两个工作向量WORK:=AVAILABLE;FINISH[i]=FALSE

(2) 从进程集合中找到一个满足下述条件的进程 

a. FINISH[i]=FALSE

b. NEED<=WORK

如找到,执行(3);否则,执行(4)。

(3) 当进程获得资源,可顺利执行,直至完成,从而释放资源。

WORK:=WORK+ALLOCATION ;

FINISH[i]:=TRUE ;

GO TO  (2)

(4) 如所有的进程FINISH[i]=TRUE,则表示安全;否则系统处于不安全状态

三、设计思想

(1)进行T0时刻的安全性检查,即在T0时刻若能找到一个安全序列,则系统是安全的。

(2)以后若有进程发出资源请求,先要判断其合法性,需满足两个条件。即判断请求的各资源数目是否都小于或者等于该进程执行完成所需的各资源数目,接着再判断请求的各资源数目是否都小于或者等于系统当前可分配的各资源数目。若不满足以上两个条件,系统不分配资源给它,让该进程等待。

(3)若满足步骤(2)的两个条件,则系统假定可为该进程分配资源,并修改该进程的相关参数(最大需求数,已分配资源数,仍需资源数)以及系统当前的资源可分配数。

(4)再利用安全性算法检查此时系统是否安全,如果能找到一个安全序列,则可判定系统是安全的,可以立即将该进程所申请的资源分配给它。否则,系统不分配资源给它,让该进程等待。

(5)循环步骤(2)至步骤(4),直至各进程都执行完毕

四、代码

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. const int M=5;//进程数
  5. const int N=3;//资源数
  6. int maxRequest [M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};//最大需求矩阵
  7. int available [N]= {3,3,2};//可用资源向量
  8. int allocation [M][N]={{0, 1,0,} ,{2,0,0},{3,0,2}, {2, 1, 1},{0,0,2}};//己分配资源矩阵
  9. int need[M][N]={{7,4,3}, {1,2,2},{6,0,0}, {0,1,1},{4,3,1}};//需求矩阵矩阵 表示每个进程还需要的各类资源的数目
  10. int request [N]={0, 0, 0} ;//资源请求
  11. int work[N];
  12. bool Finish [5];
  13. void showmaxRequest( ) //显示最大需求矩阵
  14. {
  15. cout<<"max"<<endl;
  16. for(int i=0;i<M;i++)
  17. {
  18. for(int j= 0;j<N;j++)
  19. {
  20. cout<<maxRequest[i][j]<<" ";
  21. }
  22. cout<<" ";
  23. }
  24. cout<<endl;
  25. }
  26. void showallocation() //显示己分配资源矩阵
  27. {
  28. cout<<"allocation"<<endl;
  29. for(int i=0;i<M;i++)
  30. {
  31. for(int j= 0;j<N;j++)
  32. {
  33. cout<<allocation[i][j]<<" ";
  34. }
  35. cout<<" ";
  36. }
  37. cout<<endl;
  38. }
  39. void showneed() //显示每个进程还需要的各类资源的数目
  40. {
  41. cout<<"need"<<endl;
  42. for(int i=0;i<M;i++)
  43. {
  44. for(int j= 0;j<N;j++)
  45. {
  46. cout<<need[i][j]<<" ";
  47. }
  48. cout<<" ";
  49. }
  50. cout<<endl;
  51. }
  52. void show()//显示资源分配情况
  53. {
  54. cout<<"可用资源数为:"<<endl;
  55. for(int i=0;i<N;i++)
  56. {
  57. cout<<"资源"<<i<<":"<<available[i]<<endl;
  58. }
  59. cout<<"当前的分配情况:"<<endl;
  60. cout<<"进程"<<endl;
  61. for(int i=0;i<5;i++ )//输出5个进程
  62. {
  63. cout<<"p"<<i<<" " ;
  64. }
  65. cout<<endl;
  66. showmaxRequest( );
  67. showallocation();
  68. showneed();
  69. }
  70. int Safe()
  71. {//安全性算法(核心算法)
  72. vector<int>s;
  73. int work[N];
  74. for(int i=0;i<N;i++)
  75. {
  76. work[i]=available[i];
  77. }
  78. int i,j;
  79. int count=0;//记录finish为true的个数
  80. for( i =0;i<M;i++)
  81. {
  82. Finish[i]=false;//finish表示系统是否有足够的资源分配给进程,开始时,先让每个进程置为false
  83. }
  84. while(count != M)//count等于进程数M时,表示系统处于安全状态
  85. {
  86. if(Finish[i]!=true)//查找符合的进程
  87. {
  88. for( j = 0; j < N; j++)
  89. {
  90. if(need[i][j] > work[j])
  91. break;
  92. }
  93. if(j == N) //资源数与j相等,即need中的数都比work小
  94. {
  95. cout<<"p"<<i<<"释放后 work+allocation"<<endl;
  96. Finish[i]=true;//找到符合的进程后,将finish置为true
  97. for(int j= 0;j<N;j++)
  98. {
  99. work[j]=work[j]+allocation[i][j];//进程pi执行完成后,释放分配给它的资源
  100. cout<<work[j]<<" ";
  101. }
  102. cout<<endl;
  103. count++;
  104. s.push_back(i);//将finish为true的进程输入到 vector容器中
  105. }
  106. }
  107. i++;
  108. if(i>4)
  109. {//i>4时,进程已遍历一遍,令i=0,重新遍历
  110. i=0;
  111. }
  112. }
  113. if(count==5)//安全状态
  114. {
  115. cout<<"安全序列为:"<<endl;
  116. for(vector<int>::iterator it=s.begin();it!=s.end();it++)
  117. {
  118. cout<<"p"<<*it<<"->";
  119. }
  120. cout<<endl;
  121. return 0;
  122. }
  123. else
  124. {
  125. cout<<"分配不成功"<<endl;
  126. return -1;
  127. }
  128. }
  129. bool banker(int i){//银行家算法
  130. for(int j=0;j<N;j++){
  131. if(request[j]>need[i][j]||request[j]>available[j])//超过它所需要的资源或超过可利用的资源,都为出错
  132. return false;}
  133. for(int j=0;j<N;j++) //系统试探着把资源分配给进程,并修改相应的数据
  134. {
  135. available[j]=available[j]-request[j];
  136. allocation[i][j]=allocation[i][j]+request[j];
  137. need[i][j]=need[i][j]-request[j];
  138. }
  139. if(Safe() ) return true;//如果安全,则返回
  140. else//否则,需将试探后 修改的相应数值恢复为原来的资源分配状态,让进程等待
  141. {
  142. for(int i=0;i<M;i++)
  143. {
  144. for(int j=0;j<N;j++)
  145. {
  146. available[j]=available[j]+request[j];
  147. allocation[i][j]=allocation[i][j]-request[j];
  148. need[i][j]=need[i][j]+request[j];
  149. }
  150. }
  151. return false;
  152. }
  153. }
  154. int main()
  155. {
  156. show();
  157. int i,k;
  158. cout<<" 请输入请求分配的进程"<<endl;
  159. cin>>i;
  160. cout<<"请输入请求资源数"<<endl;
  161. for(int j=0;j<N;j++)
  162. {
  163. cin>>k;
  164. request[j]=k;
  165. }
  166. banker(i);
  167. return 0;
  168. }

五、运行结果

六、结论

   通过本次实验,对银行家算法有了更深入的了解。总的来说就是从当前状态出发,逐个检查其安全性,需要的每种资源类型的最大单元数目不应该超过系统所拥有的资源总量。当进程请求一组资源时,系统必须首先确定是否有足够的资源分配给该进程。若有,再进一步计算在将这些资源分配给进程后,是否会使系统处于不安全状态。如果不会,才将资源分配给它,否则让进程等待。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/428954
推荐阅读
相关标签
  

闽ICP备14008679号