模拟银行家算法

举报
兔老大 发表于 2021/04/23 23:52:17 2021/04/23
【摘要】 介绍 data.h #ifndef _Data_h_#define _Data_h_ #include <stdio.h>#include <stdlib.h>#include <string.h> #define ElemType PCB#define Status int#define true 1#define false 0...

介绍

data.h


  
  1. #ifndef _Data_h_
  2. #define _Data_h_
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #define ElemType PCB
  7. #define Status int
  8. #define true 1
  9. #define false 0
  10. #define OK 1
  11. #define ERROR 0
  12. #define RESOURCE_NUM 3
  13. #define MAX_RESOURCE_A_NUM 10
  14. #define MAX_RESOURCE_B_NUM 5
  15. #define MAX_RESOURCE_C_NUM 7
  16. #define NAME_MAXSIZE 20
  17. #define PCB_Num 5
  18. typedef struct{
  19. int MaxNum[RESOURCE_NUM]; //需要每项资源个数
  20. int AllocationNum[RESOURCE_NUM]; //已占用每项资源个数
  21. int NeedNum[RESOURCE_NUM]; //还需要的每项资源个数
  22. }ResourceList;
  23. typedef struct
  24. {
  25. char Name[NAME_MAXSIZE]; //进程名
  26. ResourceList resList; //资源清单
  27. }PCB;
  28. typedef struct Node
  29. {
  30. ElemType data;
  31. struct Node * Next;
  32. }LNode,*LinkList;
  33. #endif

chainlist.h


  
  1. #ifndef _ChainList_h_
  2. #define _ChainList_h_
  3. #include "Data.h"
  4. Status Init(LinkList *L);
  5. void Assignment(ElemType *e1, ElemType e2);
  6. Status ListInsert_L(LinkList L,ElemType e);
  7. #endif

实现

ProPCB.h


  
  1. #ifndef _ProPCB_h_
  2. #define _ProPCB_h_
  3. #include "ChainList.h"
  4. #include <string.h>
  5. //上队列
  6. Status GetProcess(LinkList Q,ElemType e);
  7. //银行家算法
  8. Status BankerAlgorithm(int *Allocation, int *Request,int i, int *Need, int *Available);
  9. //安全性检测算法
  10. Status SecurityCheck(int *Allocation,int *Need, int *Available);
  11. //分配资源
  12. Status AllocateResource(LinkList PCBdata , int pos , int *Request);
  13. //获取资源矩阵
  14. void GetMatrixData(LinkList PCBdata,int *Max,int *Allocation,int *Need,int *Available);
  15. //打印进程资源信息
  16. void PrintProQueue(LinkList L, int *A);
  17. //得到指定PCB名的位置
  18. void GetPos(LinkList L, char *name, int len, int *pos);
  19. //对当前的请求进行预分配
  20. void PreGrant(int* Allocation, int *Request,int pos,int *Need, int *Available);
  21. //正式分配算法
  22. void GrantSource(LinkList L, int *Request, int pos, int *Available);
  23. #endif

chainlist.c


  
  1. #include "ChainList.h"
  2. extern int CPUUsedTime;
  3. Status Init(LinkList *L)
  4. {
  5. *L = (LinkList)malloc(sizeof(LNode));
  6. strcpy((*L)->data.Name, "");
  7. (*L)->Next = NULL;
  8. return OK;
  9. }
  10. void Assignment(ElemType *e1, ElemType e2)
  11. {
  12. int i = 0;
  13. strcpy(e1->Name,e2.Name);
  14. for(i = 0; i < RESOURCE_NUM; ++i)
  15. {
  16. e1->resList.AllocationNum[i] = e2.resList.AllocationNum[i];
  17. e1->resList.MaxNum[i] = e2.resList.MaxNum[i];
  18. e1->resList.NeedNum[i] = e2.resList.NeedNum[i];
  19. }
  20. }
  21. Status ListInsert_L(LinkList L,ElemType e) //这样修改应该不对 p = *L出错
  22. {
  23. LinkList p = L, s;
  24. while (p->Next)
  25. p = p->Next;
  26. s = (LinkList)malloc(sizeof(LNode));
  27. Assignment(&s->data, e);
  28. s->Next = p->Next;
  29. p->Next = s;
  30. return OK;
  31. }

ProPCB.c


  
  1. #include "ProPCB.h"
  2. Status GetProcess(LinkList Q,ElemType e)
  3. {
  4. return ListInsert_L(Q, e);
  5. }
  6. Status AllocateResource(LinkList PCBdata , int pos , int *Request)
  7. {
  8. int i = 1;
  9. LNode *p = PCBdata->Next;
  10. while (p && i < pos)
  11. {
  12. p = p->Next;
  13. ++i;
  14. }
  15. if(!p || i > pos)
  16. return ERROR;
  17. for (i = 0; i < RESOURCE_NUM; ++i)
  18. {
  19. p->data.resList.AllocationNum[i] += Request[i];
  20. p->data.resList.NeedNum[i] -= Request[i];
  21. }
  22. return OK;
  23. }
  24. void GetMatrixData(LinkList PCBdata,int *Max,int *Allocation,int *Need,int *Available)
  25. {
  26. LNode *p;
  27. int i, j, c = RESOURCE_NUM;
  28. Available[0] = Available[1] = Available[2] = 0;
  29. for(p = PCBdata->Next, i = 0; p; p = p->Next, ++i)
  30. {
  31. for(j = 0; j < RESOURCE_NUM; ++j)
  32. {
  33. Max[i * c + j] = p->data.resList.MaxNum[j];
  34. Allocation[i * c + j] = p->data.resList.AllocationNum[j];
  35. Need[i * c + j] = p->data.resList.NeedNum[j];
  36. }
  37. Available[0] += Allocation[i * c + 0];
  38. Available[1] += Allocation[i * c + 1];
  39. Available[2] += Allocation[i * c + 2];
  40. }
  41. Available[0] = MAX_RESOURCE_A_NUM - Available[0];
  42. Available[1] = MAX_RESOURCE_B_NUM - Available[1];
  43. Available[2] = MAX_RESOURCE_C_NUM - Available[2];
  44. }
  45. void PrintProQueue(LinkList L,int *available)
  46. {
  47. int i = 0;
  48. L = L->Next;
  49. printf(" -------------------------------------------------------------\n");
  50. printf("|进程名 | Max | Allocation | Need | Available |\n");
  51. printf("| | A B C | A B C | A B C | A B C |\n");
  52. while(L)
  53. {
  54. printf("| %s | %d %d %d | %d %d %d | %d %d %d | %d %d %d |\n",
  55. L->data.Name, L->data.resList.MaxNum[0], L->data.resList.MaxNum[1], L->data.resList.MaxNum[2],
  56. L->data.resList.AllocationNum[0],L->data.resList.AllocationNum[1],L->data.resList.AllocationNum[2],
  57. L->data.resList.NeedNum[0],L->data.resList.NeedNum[1],L->data.resList.NeedNum[2],
  58. available[0], available[1], available[2]);
  59. L = L->Next;
  60. }
  61. printf(" -------------------------------------------------------------\n");
  62. }
  63. //安全性检测算法
  64. Status SecurityCheck(int *Allocation,int *Need, int *Available)
  65. {
  66. / 以下补充 //
  67. int work[RESOURCE_NUM];
  68. int Finish[PCB_Num];
  69. int k, i, j, t, f;
  70. int flag;
  71. //初始化工作向量和标记数组
  72. memcpy(work, Available, sizeof work);
  73. memset(Finish, 0, sizeof Finish);
  74. //最多检测PCB_Num次
  75. for(k = 0; k < PCB_Num; ++k){
  76. flag = 0;
  77. for(i = 0; i < PCB_Num; ++i){
  78. //已经被访问
  79. if(Finish[i]){
  80. continue;
  81. }
  82. //检测是否所有资源都能被分配
  83. for(j = 0; j < RESOURCE_NUM; ++j){
  84. if(!(Need[i * 3 + j] <= work[j])){
  85. break;
  86. }
  87. }
  88. //可以满足,回收
  89. if(j == RESOURCE_NUM){
  90. for(t = 0; t < RESOURCE_NUM; ++t){
  91. work[t] += Allocation[i * 3 + t];
  92. }
  93. Finish[i] = 1;
  94. flag = 1;
  95. break;
  96. }
  97. }
  98. //为进行分配,跳出循环
  99. if(!flag){
  100. break;
  101. }
  102. }
  103. for(f = 0; f < PCB_Num; ++f){
  104. //只要有一个进程不满足,跳出循环
  105. if(!Finish[f]){
  106. return ERROR;
  107. }
  108. }
  109. return OK;
  110. }
  111. //银行家算法
  112. Status BankerAlgorithm(int* Allocation, int *Request,int pos,int *Need, int *Available)
  113. {
  114. / 以下补充 //
  115. int i;
  116. //检查请求的是否大于需要的
  117. for(i = 0; i < RESOURCE_NUM; ++i){
  118. if(Request[i] > Need[pos*3 + i]){
  119. return ERROR;
  120. }
  121. }
  122. //检查请求的是否大于可分配的
  123. for(i = 0; i < RESOURCE_NUM; ++i){
  124. if(Request[i] > Available[i]){
  125. return ERROR;
  126. }
  127. }
  128. //进行预分配
  129. PreGrant(Allocation, Request, pos, Need, Available);
  130. //进行安全性检测
  131. if(!SecurityCheck(Allocation, Need, Available)){
  132. return ERROR;
  133. }
  134. return OK;
  135. }
  136. //根据PCB的名字得到该PCB在链表中的位置
  137. void GetPos(LinkList L, char *name, int len, int *pos)
  138. {
  139. LinkList p = L->Next;
  140. char PcbName[NAME_MAXSIZE];
  141. memcpy(PcbName, name, (len + 1) * sizeof(char));
  142. (*pos) = 0;
  143. while(p){
  144. if(strcmp(p->data.Name, PcbName)){
  145. (*pos)++;
  146. p = p->Next;
  147. } else {
  148. break;
  149. }
  150. }
  151. }
  152. //预分配算法
  153. void PreGrant(int* Allocation, int *Request,int pos,int *Need, int *Available){
  154. int i;
  155. //1. Need减去请求的
  156. for(i = 0; i < RESOURCE_NUM; ++i){
  157. Need[pos*3 + i] -= Request[i];
  158. }
  159. //2. Available减去请求的
  160. for(i = 0; i < RESOURCE_NUM; ++i){
  161. Available[i] -= Request[i];
  162. }
  163. //3. Allocation加上请求的
  164. for(i = 0; i < RESOURCE_NUM; ++i){
  165. Allocation[pos*3 + i] += Request[i];
  166. }
  167. }
  168. /**
  169. * 1.首先对请求资源的进程进行分配资源
  170. * 2.如果给该进程分配资源之后,该进程所需的资源等于已经得到的资源,那么对其拥有的资源进行回收
  171. */
  172. //正式分配算法,pos从0开始标记
  173. void GrantSource(LinkList L, int *Request, int pos, int *Available){
  174. LinkList p = L->Next;
  175. int tag = 0;
  176. int i;
  177. int flag = 0;
  178. if(tag < pos && NULL != p){
  179. p = p->Next;
  180. tag++;
  181. }
  182. if(p){
  183. //已获得的加上请求的
  184. for(i = 0; i < RESOURCE_NUM; ++i){
  185. p->data.resList.AllocationNum[i] += Request[i];
  186. }
  187. //还需要的减去请求的
  188. for(i = 0; i < RESOURCE_NUM; ++i){
  189. p->data.resList.NeedNum[i] -= Request[i];
  190. }
  191. //可利用的减去请求的
  192. for(i = 0; i < RESOURCE_NUM; ++i){
  193. Available[i] -= Request[i];
  194. }
  195. //如果进行分配之后该进程最大所需资源数目等于已获得的资源数目,则对资源进行回收
  196. flag = 0;
  197. for(i = 0; i < RESOURCE_NUM; ++i){
  198. if(p->data.resList.AllocationNum[i] != p->data.resList.MaxNum[i]){
  199. flag = 1;
  200. break;
  201. }
  202. }
  203. if(!flag){
  204. for(i = 0; i < RESOURCE_NUM; ++i){
  205. Available[i] += p->data.resList.AllocationNum[i];
  206. }
  207. }
  208. }
  209. }

main


  
  1. #include "ProPCB.h"
  2. void InputData(LinkList * pPCBdata)
  3. {
  4. ElemType e = {{0},{{0},{0},{0}}};
  5. strcpy(e.Name,"P0");
  6. e.resList.MaxNum[0] = 7; e.resList.MaxNum[1] = 5; e.resList.MaxNum[2] = 3;
  7. e.resList.AllocationNum[0] = 0;
  8. e.resList.AllocationNum[1] = 1;
  9. e.resList.AllocationNum[2] = 0;
  10. e.resList.NeedNum[0] = 7; e.resList.NeedNum[1] = 4; e.resList.NeedNum[2] = 3;
  11. GetProcess(*pPCBdata,e);
  12. strcpy(e.Name,"P1");
  13. e.resList.MaxNum[0] = 3; e.resList.MaxNum[1] = 2; e.resList.MaxNum[2] = 2;
  14. e.resList.AllocationNum[0] = 2;
  15. e.resList.AllocationNum[1] = 0;
  16. e.resList.AllocationNum[2] = 0;
  17. e.resList.NeedNum[0] = 1; e.resList.NeedNum[1] = 2; e.resList.NeedNum[2] = 2;
  18. GetProcess(*pPCBdata,e);
  19. strcpy(e.Name,"P2");
  20. e.resList.MaxNum[0] = 9; e.resList.MaxNum[1] = 0; e.resList.MaxNum[2] = 2;
  21. e.resList.AllocationNum[0] = 3;
  22. e.resList.AllocationNum[1] = 0;
  23. e.resList.AllocationNum[2] = 2;
  24. e.resList.NeedNum[0] = 6; e.resList.NeedNum[1] = 0; e.resList.NeedNum[2] = 0;
  25. GetProcess(*pPCBdata,e);
  26. strcpy(e.Name,"P3");
  27. e.resList.MaxNum[0] = 2; e.resList.MaxNum[1] = 2; e.resList.MaxNum[2] = 2;
  28. e.resList.AllocationNum[0] = 2;
  29. e.resList.AllocationNum[1] = 1;
  30. e.resList.AllocationNum[2] = 1;
  31. e.resList.NeedNum[0] = 0; e.resList.NeedNum[1] = 1; e.resList.NeedNum[2] = 1;
  32. GetProcess(*pPCBdata,e);
  33. strcpy(e.Name,"P4");
  34. e.resList.MaxNum[0] = 4; e.resList.MaxNum[1] = 3; e.resList.MaxNum[2] = 3;
  35. e.resList.AllocationNum[0] = 0;
  36. e.resList.AllocationNum[1] = 0;
  37. e.resList.AllocationNum[2] = 2;
  38. e.resList.NeedNum[0] = 4; e.resList.NeedNum[1] = 3; e.resList.NeedNum[2] = 1;
  39. GetProcess(*pPCBdata,e);
  40. }
  41. int main(void)
  42. {
  43. LinkList PCBdata; //PCBdata里面存放原始数据
  44. ElemType e = {{0},{{0},{0},{0}}};
  45. char PcbName[NAME_MAXSIZE], chioce;
  46. int Max[PCB_Num][RESOURCE_NUM] = {0}, Allocation[PCB_Num][RESOURCE_NUM] = {0};
  47. int Need[PCB_Num][RESOURCE_NUM] = {0}, Available[RESOURCE_NUM] = {0};
  48. int Request[RESOURCE_NUM] = {0}, pos = 0;
  49. LNode *p = NULL;
  50. int i;
  51. / 以下补充 //
  52. //初始化就绪队列
  53. Init(&PCBdata);
  54. //数据输入
  55. InputData(&PCBdata);
  56. while(1){
  57. //获取所有PCB中的资源信息
  58. GetMatrixData(PCBdata, *Max, *Allocation, *Need, Available);
  59. //打印当前系统的状态
  60. PrintProQueue(PCBdata, Available);
  61. //接受请求
  62. printf("请输入申请资源的进程名,资源A,资源B,资源C申请量(空格隔开):");
  63. scanf("%s", PcbName);
  64. for(i = 0; i < RESOURCE_NUM; ++i){
  65. scanf("%d", &Request[i]);
  66. }
  67. //获取相应的PCB在链表中的位置
  68. GetPos(PCBdata, PcbName, strlen(PcbName), &pos);
  69. //跑银行家算法,根据返回值的状态判断是否安全,
  70. //如果安全,进行正式分配,否则仅仅打印不安全信息
  71. if(BankerAlgorithm(*Allocation, Request, pos, *Need, Available)){
  72. //正式分配资源
  73. GrantSource(PCBdata, Request, pos, Available);
  74. //分配完成后,打印资源的信息
  75. GetMatrixData(PCBdata, *Max, *Allocation, *Need, Available);
  76. PrintProQueue(PCBdata, Available);
  77. printf("请安任意键继续. . . ");
  78. getchar();
  79. getchar();
  80. } else {
  81. printf("不安全,不可分配!\n");
  82. }
  83. }
  84. return 0;
  85. }

 

文章来源: fantianzuo.blog.csdn.net,作者:兔老大RabbitMQ,版权归原作者所有,如需转载,请联系作者。

原文链接:fantianzuo.blog.csdn.net/article/details/102896482

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。