之前写过一篇关于死锁和银行家算法的详细描述的博客https://www.cnblogs.com/wkfvawl/p/11598647.html
写这篇博客的目的,主要是详细讲解一下银行家算法以及代码的实现
Dijkstra在1965年提出的银行家算法是著名的死锁避免算法,这个用于一个银行家给多个顾客贷款的算法可以直接用于操作系统给进程分配资源,这时只要把银行家换成操作系统,把顾客换成进程,把资金换成资源,把银行家决定是否放贷时所用的判断过程(即判断顾客是否有信誉和偿还能力)换成操作系统决定是否分配资源时所用的判断过程(即判断进程是否能及时归还资源)即可。为了描述银行家算法,下面先介绍一下系统的安全状态的概念。

一、安全序列

image.png
注意:
(1)系统在某一时刻的安全状态可能不唯一,但这不影响对系统安全性的判断。
(2)安全状态是非死锁状态,而不安全状态并不一定是死锁状态。即系统处于安全状态一定可以避免死锁,而系统处于不安全状态则仅仅可能进入死锁状态。
image.png

二、银行家算法

银行家算法的实质就是要设法保证系统动态分配资源后不进入不安全状态,以避免可能产生的死锁。即没当进程提出资源请求且系统的资源能够满足该请求时,系统将判断满足此次资源请求后系统状态是否安全,如果判断结果为安全,则给该进程分配资源,否则不分配资源,申请资源的进程将阻塞。
银行家算法的执行有个前提条件,即要求进程预先提出自己的最大资源请求,并假设系统拥有固定的资源总量。下面介绍银行家算法所用的主要的数据结构。
操作系统——银行家算法(Banker's Algorithm) - 图3 image.png操作系统——银行家算法(Banker's Algorithm) - 图5

三、具体实例

假定操作系统中的4个进程P1、P2、P3、P4和3类资源R1、R2、R3(资源数量分别为9、3、6),在t0时刻的资源分配情况如表2-1:
操作系统——银行家算法(Banker's Algorithm) - 图6操作系统——银行家算法(Banker's Algorithm) - 图7操作系统——银行家算法(Banker's Algorithm) - 图8操作系统——银行家算法(Banker's Algorithm) - 图9操作系统——银行家算法(Banker's Algorithm) - 图10操作系统——银行家算法(Banker's Algorithm) - 图11操作系统——银行家算法(Banker's Algorithm) - 图12

四、测试代码

  1. #include<iostream>
  2. using namespace std;
  3. // p 进程数,r资源种类
  4. int p ;
  5. int r ;
  6. int maxs[10][10]; //最大需求矩阵
  7. int allocation[10][10]; //分配矩阵
  8. int need[10][10]; //需求矩阵
  9. int available[10]; //可用资源向量
  10. int request[10]; //请求向量当前进程对各类资源的申请量,算法的入口参数
  11. //输入函数
  12. void infInput()
  13. {
  14. int i,j;
  15. cout<<"请输入最大需求矩阵max\n";
  16. for(i=0; i<p; i++)
  17. {
  18. for(j=0; j<r; j++)
  19. {
  20. cin>>maxs[i][j];
  21. }
  22. }
  23. cout<<"请输入分配矩阵allocation\n";
  24. for(i=0; i<p; i++)
  25. {
  26. for(j=0; j<r; j++)
  27. {
  28. cin>>allocation[i][j];
  29. }
  30. }
  31. cout<<"请输入需求矩阵need\n";
  32. for(i=0; i<p; i++)
  33. {
  34. for(j=0; j<r; j++)
  35. {
  36. cin>>need[i][j];
  37. }
  38. }
  39. cout<<"请输入可用资源向量available\n";
  40. for(i=0; i<r; i++)
  41. {
  42. cin>>available[i];
  43. }
  44. }
  45. //比较函数
  46. //比较进程为m中的元素全大于n中的元素返回1,否则返回0
  47. int compare(int m[],int n[])
  48. {
  49. int i;
  50. for(i=0; i<r; i++)
  51. {
  52. if(m[i]<n[i])
  53. {
  54. return 0;
  55. }
  56. }
  57. return 1;
  58. }
  59. //安全性检验函数,检测是否存在安全序列
  60. int stest()
  61. {
  62. int i,j,k,l,flag=0;
  63. int finish[p];
  64. int work[r];
  65. for(i=0; i<p; i++)
  66. {
  67. finish[i]=0;
  68. //vis为1即表示available满足第i进程的资源需要
  69. }
  70. for(i=0; i<r; i++)
  71. {
  72. work[i]=available[i];
  73. }
  74. cout<<"分配序列:\n";
  75. cout<<" allocation need avilable"<<endl;
  76. for(k=0; k<p; k++)
  77. {
  78. for(i=0; i<p; i++)
  79. {
  80. if(finish[i]==1)
  81. {
  82. continue;
  83. }
  84. else
  85. {
  86. if(compare(work,need[i]))//available>=need
  87. {
  88. finish[i]=1;
  89. cout<<'\n'<<"进程"<<i+1<<'\t';
  90. flag=1;
  91. for (j =0; j<r; j++)
  92. {
  93. printf(" %2d ", allocation[i][j]);
  94. }
  95. cout<<" ";
  96. for (j = 0; j < r; j++)
  97. {
  98. printf(" %2d ", need[i][j]);
  99. }
  100. cout<<" ";
  101. for (j = 0; j <r; j++)
  102. {
  103. printf(" %2d ", work[j] +allocation[i][j]);
  104. }
  105. for(l=0; l<r; l++)
  106. {
  107. work[l]=work[l]+allocation[i][l];
  108. //进程完成,释放资源
  109. }
  110. break;
  111. }
  112. }
  113. if(flag==1)
  114. {
  115. break;
  116. }
  117. }
  118. }
  119. cout<<'\n';
  120. for(l=0; l<p; l++)
  121. {
  122. if(finish[l]==0)
  123. {
  124. return 0;//不存在安全序列
  125. }
  126. }
  127. return 1;//存在安全序列
  128. }
  129. //申请进程后的安全性检验函数
  130. void rtest(int n)
  131. {
  132. int j;
  133. //n=n-1;
  134. if(compare(available,request)&&compare(need[n-1],request))//available>=request 并且 need >=request
  135. {
  136. for(j=0; j<r; j++)
  137. {
  138. allocation[n-1][j]=allocation[n-1][j]+request[j];
  139. need[n-1][j]=need[n-1][j]-request[j];
  140. available[j]=available[j]-request[j];
  141. }
  142. if(stest())
  143. {
  144. cout<<"允许"<<n<<"进程申请资源!\n";
  145. }
  146. else
  147. {
  148. cout<<"不允许"<<n<<"进程申请资源!\n";
  149. for(j=0; j<r; j++)
  150. {
  151. allocation[n-1][j]=allocation[n-1][j]-request[j];
  152. need[n-1][j]=need[n-1][j]+request[j];
  153. available[j]=available[j]+request[j];
  154. }
  155. }
  156. }
  157. else
  158. {
  159. cout<<"申请资源量越界!\n";
  160. }
  161. }
  162. int main()
  163. {
  164. int i,n; //n-第n个资源申请
  165. cout<<"请输入进程数:";
  166. cin>>p;
  167. cout<<"请输入资源种类数:";
  168. cin>>r;
  169. //默认状态4、3
  170. infInput();//输入函数
  171. if(stest()==1)
  172. {
  173. cout<<"存在安全序列,初始状态安全。\n";
  174. }
  175. else
  176. {
  177. cout<<"不存在安全序列,初始状态不安全。\n";
  178. }
  179. cout<<"请输入发出请求向量request的进程编号:";
  180. cin>>n;
  181. cout<<"请输入请求向量request\n";
  182. for(i=0; i<r; i++)
  183. {
  184. cin>>request[i];
  185. }
  186. rtest(n);
  187. return 0;
  188. }
  189. /*
  190. 4
  191. 3
  192. 3 2 2
  193. 6 1 3
  194. 3 1 4
  195. 4 2 2
  196. 1 0 0
  197. 5 1 1
  198. 2 1 1
  199. 0 0 2
  200. 2 2 2
  201. 1 0 2
  202. 1 0 3
  203. 4 2 0
  204. 1 1 2
  205. */

操作系统——银行家算法(Banker's Algorithm) - 图13