• 银行家算法程序模拟实现


     代码仓库:JJLi0427/operationsystem (github.com)

    1.算法简介

    银行家算法是一种用于避免死锁的算法,其主要应用于多进程环境下的资源分配问题。在银行家算法中,每个进程都需要申请一定数量的资源,而系统会根据当前资源的可用性来判断是否能够满足该进程的资源需求,从而决定是否分配资源。

    一个典型的银行家算法问题可以描述如下:假设有n个进程和m种不同类型的资源,每个进程需要一定数量的每种资源才能完成任务。系统中有一定数量的每种资源可供分配,但是不同的进程对资源的需求量不同。现在需要设计一个算法,以确保系统能够分配资源并避免死锁

    2.解决思路

    想解决银行家问题就需要回答以下问题:

    1. 每个进程需要的资源量是多少?(建立需求矩阵)

    2. 系统中有多少可用的每种资源?(建立可用资源向量)

    3. 系统是否能够满足当前进程的资源需求?(安全性判断)

    4. 如果系统不能满足当前进程的资源需求,该进程应该如何等待?(计算安全序列)

    5. 当系统分配资源后,是否会导致死锁?(不安全退回)

    3.模拟实现程序设计思路 

    1. 首先,在全局变量中定义进程数量p、资源种类r以及已分配资源矩阵allocate、需求资源矩阵needs和可利用资源向量avail。

    2. 通过init函数进行初始化,将已分配资源矩阵、需求资源矩阵和最大需求资源矩阵进行赋值。其中,最大需求资源矩阵的值等于已分配资源矩阵加上需求资源矩阵。

    3. 编写output函数,用于输出最大需求资源矩阵、已分配资源矩阵、需求资源矩阵和可利用资源向量的值。

    4. 编写compare函数用于比较进程的需求资源和可用资源,判断是否满足分配条件。

    5. safe函数用于进行安全性检查,采用银行家算法判断系统是否处于安全状态。具体步骤如下:

      • 初始化finish数组、forwork数组、安全队列list和计数器count。
      • 尝试为每个未完成的进程分配资源,如果该进程的需求资源小于等于可用资源,则将其加入安全队列,并更新可用资源。
      • 如果所有进程都能成功分配资源,则系统处于安全状态,输出安全队列。
      • 如果存在无法分配资源的进程,则系统不安全。
    6. bank函数用于处理用户的请求。首先获取用户输入的进程号和请求向量,然后进行以下判断:

      • 请求向量不能大于需求向量。
      • 请求向量不能大于可利用资源向量。
      • 如果满足以上条件,尝试为该进程分配资源,并进行安全性检查。
      • 如果分配成功,则输出"Allocate success",否则输出"Allocate fail"。
    7. 主函数中,先调用init函数进行初始化,并输出初始状态。然后进行一次安全性检查。接着进入循环,每次循环都调用bank函数处理用户的请求,并询问用户是否继续或退出。

    4.完整程序

    1. #include
    2. using namespace std;
    3. const int p = 5; // 设置进程数量
    4. const int r = 4; // 设置资源种类
    5. int allocate[p][r] = {{0, 1, 0, 0},
    6. {2, 0, 0, 1},
    7. {3, 0, 2, 1},
    8. {2, 1, 1, 0},
    9. {0, 0, 2, 0}}; // 已分配资源矩阵
    10. int needs[p][r] = {{7, 4, 3, 3},
    11. {1, 2, 2, 2},
    12. {6, 0, 0, 0},
    13. {0, 1, 1, 1},
    14. {4, 3, 1, 1}}; // 需求资源矩阵
    15. int avail[r] = {3, 3, 2, 2}; // 可利用资源向量
    16. void init(int maximum[p][r], int allocation[p][r], int need[p][r], int available[r], int request[r]) {
    17. for(int i = 0; i < p; i++) {
    18. for(int j = 0; j < r; j++) {
    19. allocation[i][j] = allocate[i][j];
    20. need[i][j] = needs[i][j];
    21. maximum[i][j] = need[i][j]+allocation[i][j]; // maximum = allocation + need
    22. }
    23. } // 初始化,从矩阵读取数据
    24. for(int i = 0; i < r; i++) {
    25. available[i] = avail[i];
    26. }
    27. }
    28. void output(int maximum[p][r], int allocation[p][r], int need[p][r], int available[r]) {
    29. cout << "Maximum: " << "Allocation: " << "Need: " << "Available: " << endl;
    30. for(int i = 0; i < p; i++) {
    31. cout << "Pid=" << i << ": ";
    32. for(int j = 0; j < r; j++) {
    33. cout << maximum[i][j] << ' ';
    34. }
    35. cout << " Pid=" << i << ": ";
    36. for(int j = 0; j < r; j++) {
    37. cout << allocation[i][j] << ' ';
    38. }
    39. cout << " Pid=" << i << ": ";
    40. for(int j = 0; j < r; j++) {
    41. cout << need[i][j] << ' ';
    42. }
    43. if(i == 0) {
    44. cout << " ";
    45. for(int k = 0; k < r; k++){
    46. cout << available[k] << ' ';
    47. }
    48. }
    49. cout << endl;
    50. }
    51. }
    52. bool compare(int need[], int forwork[]) {
    53. // 比较函数,需要<=可用
    54. for(int i = 0; i < r; i++) {
    55. if(need[i] > forwork[i]) {
    56. return false;
    57. }
    58. }
    59. return true;
    60. }
    61. bool safe(int allocation[p][r], int need[p][r], int available[r]) {
    62. // 安全性检查
    63. int finish[p]; // finish数组,用来记录进程是可以否执行完成
    64. int forwork[r]; // 可用资源数组
    65. int list[p]; // 安全队列
    66. int count = 0;
    67. for(int i = 0; i < r; i++)
    68. forwork[i] = available[i]; // 初始时等于available
    69. for(int x = 0; x < p; x++) {
    70. for(int i = 0; i < p; i++) {
    71. if(finish[i] == 1)
    72. continue; // 跳过已经判断过的进程
    73. else {
    74. if(compare(need[i], forwork)) {
    75. for(int j = 0; j < r; j++) {
    76. forwork[j] += allocation[i][j];
    77. }
    78. finish[i] = 1;
    79. list[count++] = i; // 进程进入安全列中
    80. break;
    81. }
    82. }
    83. }
    84. }
    85. if(count != p) {
    86. cout << "Will not be safe!" << endl;
    87. return false;
    88. }
    89. cout << "Safe! working list: ";
    90. for(int i = 0; i < p; i++) {
    91. cout << list[i];
    92. if(i != p-1)
    93. cout << "->";
    94. }
    95. cout << endl;
    96. return true;
    97. }
    98. int bank(int maximum[p][r], int allocation[p][r], int need[p][r], int available[r], int request[r]) {
    99. cout << "Request Process id:" << endl;
    100. int num = 0;
    101. cin >> num;
    102. cout << "Request vector:" << endl;
    103. for(int i = 0; i < r; i++) {
    104. cin >> request[i];
    105. }
    106. if(!compare(request ,need[num])) {
    107. // 请求不能大于需求
    108. cout<<"Error: request > need"<
    109. return 0;
    110. }
    111. else {
    112. if(!compare(request, available)) {
    113. // 请求不能大于可用
    114. cout << "Error: request > available" << endl;
    115. return 0;
    116. }
    117. else {
    118. for(int j = 0; j < r;j ++) {
    119. available[j] -= request[j];
    120. allocation[num][j] += request[j];
    121. need[num][j] -= request[j];
    122. }
    123. if(safe(allocation, need, available)) {
    124. cout <<"Allocate success"<< endl;
    125. }
    126. else {
    127. cout << "Allocate fail" << endl;
    128. for(int j = 0; j < r; j++) {
    129. need[num][j] += request[j];
    130. allocation[num][j] -= request[j];
    131. available[j] += request[j];
    132. } // 分配失败返回原来状态
    133. }
    134. }
    135. }
    136. output(maximum, allocation, need, available);
    137. return 0;
    138. }
    139. int main() {
    140. int maximum[p][r], allocation[p][r], need[p][r];
    141. int available[r], request[r];
    142. init(maximum, allocation, need, available, request);
    143. output(maximum, allocation, need, available);
    144. safe(allocation, need, available);
    145. char flag = 'c';
    146. while(flag == 'c' || flag == 'C') {
    147. bank(maximum, allocation, need, available, request);
    148. cout << "\nInput q to left / Input c to continue." << endl;
    149. cin >> flag;
    150. if(flag == 'q' || flag == 'Q')
    151. break;
    152. }
    153. return 0;
    154. }

    5.运行截图

    先输入进程id,再输入需要申请的资源向量,继续执行输入c,结束模拟输入q

    ae7e889d397b4797a95794133a53abf0.png

  • 相关阅读:
    想要彻底搞的性能优化,得先从底层逻辑开始了解~
    rust变量与常量
    荷兰国旗问题与快速排序算法
    nginx(四十八)HTTP框架提供的变量
    MVP-3:登陆注册自定义token拦截器
    Poetry:Python依赖管理和打包工具【最好用的Python虚拟环境Poetry】【Poetry、conda、vscode混合使用】
    K8s自我探索实践心得
    mysql体系结构及引擎
    SDUT—Python程序设计实验10&11(面向对象)
    如何调试 Python 代码
  • 原文地址:https://blog.csdn.net/lijj0304/article/details/134059646