一、银行家算法

功能:避免死锁

在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还。银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要。在这样的描述中,银行家就好比操作系统,资金就是资源,客户就相当于要申请资源的进程。

二、代码实现

  1. #include <iostream>
  2. using namespace std;
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. /* 定义全局变量 */
  7. const int x = 50, y = 50; /* x为进程个数 y为资源种类数 */
  8. int Available[y]; /* 各资源可利用的数量 */
  9. int Allocation[x][y]; /* 各进程当前已分配的资源数量 */
  10. int Max[x][y]; /* 各进程对各类资源的最大需求数 */
  11. int Need[x][y]; /* 尚需多少资源 */
  12. int Request[y]; /* 申请多少资源 */
  13. int Work[y]; /* 工作向量,表示系统可提供给进程继续运行所需的各类资源数量 */
  14. int Finish[x]; /* 表示系统是否有足够的资源分配给进程,1为是 */
  15. int p[x]; /* 存储安全序列 */
  16. int i, j; /* i表示进程,j表示资源 */
  17. int n, m; /* n为进程i的数量,m为资源j种类数 */
  18. int l = 0; /* l用来记录有几个进程是Finish[i]=1的,当l=n是说明系统状态是安全的 */
  19. int counter = 0; /* 记数器,记录可执行的进程数 */
  20. /* 函数声明 */
  21. void chushihua(); /* 初始化函数 */
  22. void safe(); /* 安全性算法 */
  23. void show(); /* 函数show,输出当前状态 */
  24. void bank(); /* 银行家算法 */
  25. void jieshu(); /* 结束函数 */
  26. void chushihua()
  27. {
  28. cout << "输入进程的数量: "; /* 从此开始输入有关数据 */
  29. cin >> n;
  30. cout << "输入资源种类数: ";
  31. cin >> m;
  32. cout << endl << "输入各种资源当前可用的数量( " << m << " 种): " << endl;
  33. for ( j = 0; j < m; j++ ) /* m为资源数 */
  34. {
  35. cout << "输入资源 " << j << " 可利用的数量Available[" << j << "]: ";
  36. cin >> Available[j]; /* 输入数字的过程 */
  37. Work[j] = Available[j]; /* 初始化Work[j],它的初始值就是当前可用的资源数 */
  38. }
  39. cout << endl << "输入各进程当前已分配的资源数量Allocation[" << n << "][" << m << "]: " << endl;
  40. for ( i = 0; i < n; i++ ) /* n为进程数 */
  41. {
  42. for ( j = 0; j < m; j++ ) /* m为资源数 */
  43. {
  44. cout << " 输入进程 " << i << " 当前已分配的资源 " << j << " 数量: ";
  45. cin >> Allocation[i][j];
  46. }
  47. cout << endl;
  48. Finish[i] = 0; /* 初始化Finish[i] */
  49. }
  50. cout << endl << "输入各进程对各类资源的最大需求Max[" << n << "][" << m << "]: " << endl;
  51. for ( i = 0; i < n; i++ ) /* n为进程数 */
  52. {
  53. for ( j = 0; j < m; j++ ) /* m为资源数 */
  54. {
  55. cout << " 输入进程 " << i << " 对资源 " << j << " 的最大需求数: ";
  56. cin >> Max[i][j];
  57. if ( Max[i][j] >= Allocation[i][j] ) /* 若最大需求大于已分配,则计算需求量 */
  58. Need[i][j] = Max[i][j] - Allocation[i][j];
  59. else
  60. Need[i][j] = 0; /* Max小于已分配的时候,此类资源已足够不需再申请 */
  61. }
  62. cout << endl;
  63. }
  64. cout << endl << "初始化完成" << endl;
  65. }
  66. /* 安全性算法函数 */
  67. void safe()
  68. {
  69. l = 0; /* l用来记录有几个进程是Finish[i]=1的,当l=n是说明系统状态是安全的 */
  70. for ( i = 0; i < n; i++ ) /* n为进程数 */
  71. {
  72. if ( Finish[i] == 0 )
  73. { /* 逐个查找Finish[i]==0的进程 条件一 */
  74. counter = 0; /* 记数器,记录有多少个进程已经执行 */
  75. for ( j = 0; j < m; j++ ) /* m为资源数 */
  76. {
  77. if ( Work[j] >= Need[i][j] )
  78. counter = counter + 1; /* 可用大于需求,记数,该进程可以执行 */
  79. }
  80. if ( counter == m ) /* i进程的每类资源都符合Work[j]>=Need[i][j] 条件二 */
  81. {
  82. p[l] = i; /* 存储安全序列 */
  83. Finish[i] = 1; /* i进程标志为可分配 */
  84. for ( j = 0; j < m; j++ )
  85. Work[j] = Work[j] + Allocation[i][j]; /* 释放资源 */
  86. l = l + 1; /* 记数,现在有l个进程是安全的,当l=n时说明满足安全序列 */
  87. i = -1; /* 从第一个进程开始继续寻找满足条件一二的进程 */
  88. }
  89. }
  90. }
  91. }
  92. /* 显示当前状态函数 */
  93. void show() /* 函数show,输出当前资源分配情况 */
  94. {
  95. int i, j; /* 局部变量,i表示进程,j表示资源 */
  96. int All[y]; /* 各种资源的总数量 */
  97. int L1; /* 局部变量L1 */
  98. cout << "当前的状态为:" << endl;
  99. cout << "各种资源的总数量:" << endl;
  100. for ( j = 0; j < m; j++ ) /* m为资源数 */
  101. {
  102. cout << " 资源" << j << ": ";
  103. All[j] = Available[j]; /* 总数量=可用的+已分配的 */
  104. for ( i = 0; i < n; i++ ) /* n为进程数 */
  105. All[j] += Allocation[i][j];
  106. cout << All[j] << " ";
  107. }
  108. cout << endl << "当前各种资源可用的量为(available):" << endl;
  109. for ( j = 0; j < m; j++ ) /* m为资源数 */
  110. cout << " 资源" << j << ": " << Available[j] << " ";
  111. cout << endl << "各进程所需的最大资源量(Max): " << endl;
  112. for ( i = 0; i < m; i++ ) /* m为资源数 */
  113. {
  114. cout << " 资源" << i << " ";
  115. }
  116. cout << endl;
  117. for ( L1 = 0; L1 < n; L1++ ) /* n为进程数 */
  118. {
  119. cout << "进程" << L1 << ": ";
  120. for ( j = 0; j < m; j++ )
  121. cout << Max[L1][j] << " ";
  122. cout << endl;
  123. }
  124. cout << endl << "各进程已经得到的资源量(allocation): " << endl;
  125. for ( i = 0; i < m; i++ ) /* m为资源数 */
  126. {
  127. cout << " 资源" << i << " ";
  128. }
  129. cout << endl;
  130. for ( L1 = 0; L1 < n; L1++ ) /* n为进程数 */
  131. {
  132. cout << "进程" << L1 << ": ";
  133. for ( j = 0; j < m; j++ )
  134. cout << Allocation[L1][j] << " ";
  135. cout << endl;
  136. }
  137. cout << endl << "各进程还需要的资源量(need):" << endl;
  138. for ( i = 0; i < m; i++ ) /* m为资源数 */
  139. {
  140. cout << " 资源" << i << " ";
  141. }
  142. cout << endl;
  143. for ( L1 = 0; L1 < n; L1++ )
  144. {
  145. cout << "进程" << L1 << ": ";
  146. for ( j = 0; j < m; j++ )
  147. cout << Need[L1][j] << " ";
  148. cout << endl;
  149. }
  150. }
  151. /* 银行家算法函数 */
  152. void bank()
  153. {
  154. cout << endl << "进程申请分配资源:" << endl;
  155. int k = 0; /* 用于输入进程编号 */
  156. bool r = false; /* 初值为假,输入Y继续申请则置为真 */
  157. do /* 输入请求 */
  158. {
  159. cout << "输入申请资源的进程(0-" << n - 1 << "): ";
  160. cin >> k; /* 进程编号 */
  161. cout << endl;
  162. while ( k > n - 1 ) /* 输入错误处理 */
  163. {
  164. cout << endl << "无该进程号,重新输入:" << endl;
  165. cout << endl << "输入申请资源的进程(0--" << n - 1 << "): ";
  166. cin >> k; /* 进程编号 */
  167. cout << endl;
  168. }
  169. cout << endl << "输入该进程申请各类资源的数量: " << endl;
  170. for ( j = 0; j < m; j++ ) /* m为资源数 */
  171. {
  172. do /* do……while 循环判断申请输入的情况 */
  173. {
  174. cout << "进程 " << k << " 申请资源[" << j << "]的数量:";
  175. cin >> Request[j]; /* 输入请求进程数 */
  176. cout << endl;
  177. if ( Request[j] > Need[k][j] ) /* 申请大于需求量时出错,提示重新输入 cout<<"申请量大于需要量!"<<endl; */
  178. {
  179. cout << "申请的资源" << j << "的数量为" << Request[j] << ",大于进程" << k << "对该资源需求量" << Need[k][j] << "。" << endl;
  180. cout << "重新输入!" << endl;
  181. }
  182. /* 先判断是否申请大于需求量,再判断是否申请大于可利用量 */
  183. else if ( Request[j] > Available[j] ) /* 申请大于可利用量, 应该阻塞等待 */
  184. {
  185. cout << "\n没有那么多资源,目前可利用资源" << j << "数量为" << Available[j] << ",本次申请不成功,进程等待!" << endl;
  186. Finish[k] = 0; /* 该进程等待 */
  187. goto error; /* goto语句跳转,结束本次申请 */
  188. }
  189. }
  190. while ( Request[j] > Need[k][j] ); /* Request[j]>Available[j] */
  191. }
  192. /* 改变Available、Allocation、Need的值 */
  193. for ( j = 0; j < m; j++ ) /* m为资源数 */
  194. {
  195. Available[j] = Available[j] - Request[j]; /* 可用的资源数=可用的资源数-请求分配的资源数 */
  196. Allocation[k][j] = Allocation[k][j] + Request[j]; /* 已分配的资源数=已分配的资源数+请求的资源数 */
  197. Need[k][j] = Need[k][j] - Request[j]; /* 还需要的资源数=还需要的资源数-请求的资源数 */
  198. Work[j] = Available[j];
  199. }
  200. safe(); /* 调用安全性算法函数,判断当前状态的安全性 */
  201. if ( l < n ) /* l用来记录有几个进程是Finish[i]=1的,当l=n是说明系统状态是安全的 */
  202. {
  203. l = 0;
  204. cout << "\n试分配后,状态不安全,所以不予分配!恢复原状态" << endl;
  205. /* 恢复数据 */
  206. for ( j = 0; j < m; j++ ) /* m为资源数 */
  207. {
  208. Available[j] = Available[j] + Request[j];
  209. Allocation[k][j] = Allocation[k][j] - Request[j];
  210. Need[k][j] = Need[k][j] + Request[j];
  211. Work[j] = Available[j];
  212. }
  213. for ( i = 0; i < n; i++ ) /* n为进程数 */
  214. Finish[i] = 0; /* 进程均置为未分配状态 */
  215. }else { /* l=n,即所有的Finish[i]=1,每一个进程均能执行 */
  216. l = 0; /* 判断标志 */
  217. cout << "\n申请资源成功!!!" << endl;
  218. for ( j = 0; j < m; j++ ) /* m为资源数 */
  219. {
  220. if ( Need[k][j] == 0 )
  221. ;
  222. else { /*有一种资源还没全部申请到,则该进程不可执行,不能释放拥有的资源 */
  223. l = 1; /* 置l为1,作为判断标志 */
  224. break;
  225. }
  226. }
  227. if ( l != 1 ) /* 进程可以执行,则释放该进程的所有资源 */
  228. {
  229. for ( j = 0; j < m; j++ ) /* m为资源数 */
  230. {
  231. Available[j] = Available[j] + Allocation[k][j];
  232. Allocation[k][j] = 0;
  233. }
  234. cout << "该进程已得到所有需求资源,执行后将释放其所有拥有资源!" << endl;
  235. }
  236. l = 0; /* 归零 */
  237. cout << "\n安全的状态!" << endl;
  238. cout << "安全序列为: ";
  239. cout << endl << "进程" << "(" << p[0] << ")"; /* 输出安全序列,考虑显示格式,先输出第一个 */
  240. Finish[0] = 0;
  241. for ( i = 1; i < n; i++ )
  242. {
  243. cout << "==>>" << "进程" << "(" << p[i] << ")";
  244. Finish[i] = 0; /* 所有进程置为未分配状态 */
  245. }
  246. cout << endl << endl;
  247. }
  248. show(); /* 显示当前状态 */
  249. error: /* 申请大于可利用量, 应该阻塞等待,结束本次资源申请,GOTO 语句跳转至此 */
  250. cout << endl << "是否继续申请资源(y/n)或(Y/N)?";
  251. char* b = new char; /* 输入y/n,判断是否继续申请 <<endl */
  252. cin >> b;
  253. cout << endl;
  254. cout << "-------------------------------------------" << endl << endl;
  255. cout << endl;
  256. if ( *b == 'y' || *b == 'Y' )
  257. r = true; /* 继续申请 */
  258. else{
  259. r = false; /*不继续申请 */
  260. jieshu(); /* 调用结束函数 */
  261. }
  262. }
  263. while ( r == true );
  264. }
  265. /* 结束函数 */
  266. void jieshu()
  267. {
  268. cout << endl << endl;
  269. cout << "\t\t 演示计算完毕" << endl;
  270. cout << endl << endl;
  271. }
  272. /* 主函数 */
  273. int main()
  274. {
  275. cout << endl << endl << "\t\t\t\t模拟银行家算法" << endl << endl;
  276. chushihua(); /* 初始化函数调用 */
  277. cout << endl;
  278. show(); /* 输出当前状态 */
  279. safe(); /* 判断当前状态的安全性 */
  280. if ( l < n ) /* l在safe中是用来记录安全的进程的个数的 */
  281. {
  282. cout << "\n当前状态不安全,拒绝申请!" << endl;
  283. cout << endl;
  284. return(0);
  285. }else {
  286. int i; /* 局部变量 */
  287. l = 0;
  288. cout << endl << "\n当前的状态是安全的!安全序列为:" << endl;
  289. cout << "进程" << "(" << p[0] << ")"; /* 输出安全序列 */
  290. for ( i = 1; i < n; i++ )
  291. cout << "->>" << "进程" << "(" << p[i] << ")";
  292. for ( i = 0; i < n; i++ )
  293. Finish[i] = 0; /* 所有进程置为未分配状态 */
  294. cout << endl;
  295. }
  296. bank(); /* 调用银行家算法函数 */
  297. cout << "\t\t 演示计算完毕" << endl;
  298. return(0);
  299. }