当前位置:   article > 正文

C语言 操作系统实验二 LRU_lru c语言

lru c语言

注:

本文是两个页面淘汰模拟算法的第二篇算法。

我是个菜鸡,发文是为了纪念自己完成了代码,以及累计自己的经验。

如有知识错误或者算法有逻辑漏洞请各位大佬高抬贵手。

实验环境:win10、VS2022(C++)

PS:虽然是cpp文件,实际上是披着cpp的c

        运行前,首先要在预处理器上插入_CRT_SECURE_NO_WARNINGS,避免运行错误,在插入前要用;隔开。

核心思想:和FIFO相同,利用两条链表分别模拟内存中的页(节点为页块)、外存,数组则存放访问序列,

通过循环将逐一输出访问的页面,在交换页面时,从模拟的外存链表中循环查找后赋值给相应的节点。(注意:不同结构体不能交换节点,由于时间有限,没有考虑同一结构体下两链表的做法)

唯一区别在于,FIFO对淘汰页面采取先来先走的态度,所以在编代码时要按顺序踢掉前面的页块,设置循环标记即可

而LRU则是判断最近最久时间没来的页面,在编程时,在页块的结构中增加int frequency,每当调用页面时,将记录当前的调用次数,缺页替换时,在页面模拟链表中找出当前列表调用次数最小的即可

完整代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <conio.h>
  4. #define NULL 0
  5. #define getpch(type) (type*)malloc(sizeof(type))//创建列表是模仿页面
  6. struct Numb//页框
  7. {
  8. int num;
  9. int frequency;
  10. struct Numb* link;
  11. }*ready = NULL, * first, * p, * last;
  12. struct romnum
  13. {
  14. int n;
  15. struct romnum* link2;
  16. }*ready2 = NULL, * first2, * p2, * last2;
  17. int order[1000] = { 0 };//调用序列
  18. int page = 0;//页框数
  19. int pagenumber = 0;//页调用次数
  20. int h = 0;//记录外存链表的长度
  21. int flag = 0;//缺页记录
  22. int lack = 0;//记录缺页情况
  23. int time = 0;
  24. int log = 0;//保证在为装满页面时发生能找到相应页块的情况下不计为缺页的标志
  25. void Link()
  26. {
  27. if (ready == NULL)
  28. {
  29. ready = p;
  30. first = p;
  31. last = p;
  32. }
  33. else
  34. {
  35. last->link = p;
  36. last = p;
  37. }
  38. }
  39. void Rom(int i)
  40. {
  41. if (ready2 == NULL)//如果没有链表则创建一个链表头
  42. {
  43. p2 = getpch(romnum);
  44. p2->n = order[i];
  45. p2->link2 = NULL;
  46. ready2 = p2;
  47. first2 = p2;
  48. last2 = p2;
  49. //printf("last2->n = %d\n", last2->n);
  50. h++;
  51. }
  52. else
  53. {
  54. first2 = ready2;
  55. do//循环判断order在外存链表中是否有有相同内容,不同则存入
  56. {
  57. if (order[i] != first2->n)//如果order值不同于当前节点值,则继续查找
  58. {
  59. if (first2->link2 == NULL)//如果查到尾节点依旧没有相同值
  60. {
  61. p2 = getpch(romnum);//创建节点
  62. p2->n = order[i];
  63. p2->link2 = NULL;
  64. last2->link2 = p2;//尾节点链接新节点
  65. last2 = p2;
  66. //printf("last2->n = %d\n", last2->n);
  67. h++;
  68. break;
  69. }
  70. else//如果不在尾节点则按顺序进行查找
  71. {
  72. first2 = first2->link2;
  73. }
  74. }
  75. else
  76. {
  77. break;
  78. }
  79. } while (1);
  80. }
  81. }
  82. void input()
  83. {
  84. printf("请输入符合页框数的页面访问序列(禁止输入0):\n");
  85. for (int i = 0; i < pagenumber; i++)//记录访问序列
  86. {
  87. scanf("%d", &order[i]);
  88. /*printf("order[%d] = %d ", i, order[i]);
  89. printf("\n");*/
  90. Rom(i);
  91. }
  92. for (int i = 0; i < page; i++)//成立页
  93. {
  94. p = getpch(Numb);
  95. p->num = 0;
  96. p->frequency = 0;
  97. //printf("%d ", p->num);
  98. p->link = NULL;
  99. Link();
  100. }
  101. }
  102. void destory()
  103. {
  104. for (int i = 0; i < page; i++)
  105. {
  106. p = ready;
  107. ready = ready->link;
  108. p->link = NULL;
  109. free(p);
  110. }
  111. for (int i = 0; i < h; i++)
  112. {
  113. p2 = ready2;
  114. ready2 = ready2->link2;
  115. p2->link2 = NULL;
  116. free(p2);
  117. }
  118. }
  119. void output()
  120. {
  121. first = ready;
  122. if (flag == page || lack < page && log != 1)
  123. {
  124. printf("* ");
  125. }
  126. else
  127. {
  128. printf(" ");
  129. }
  130. for (int i = 0; i < page; i++)
  131. {
  132. printf("%d ", first->num);
  133. first = first->link;
  134. }
  135. printf("\n");
  136. }
  137. void check(int i)
  138. {
  139. first2 = ready2;
  140. for (int j = 0; j < h; j++)
  141. {
  142. if (order[i] != first2->n)
  143. {
  144. first2 = first2->link2;
  145. }
  146. else
  147. {
  148. break;
  149. }
  150. }
  151. }
  152. void LRU(int i)
  153. {
  154. log = 0;
  155. //此阶段开启时,空页应准备就绪,页的输出顺序也准备完毕,外存链表也应准备完毕
  156. for (int j = 0; j < page; j++)
  157. {
  158. if (order[i] != first->num)
  159. {
  160. if (first->num == 0)//需要填充
  161. {
  162. check(i);
  163. first->num = first2->n;
  164. first->frequency = i;
  165. output();
  166. lack++;
  167. break;
  168. }
  169. }
  170. else if (order[i] == first->num)
  171. {
  172. first->frequency = i;
  173. log = 1;
  174. output();
  175. break;//找到所需要的块
  176. }
  177. first = first->link;//运行到最后一轮为野指针
  178. flag += 1;//若flag等于page的值,说明在既没有填充,又没有相同的情况下,没有找到相同的值,表示缺页,小于则表示要么在页(链表)中找到符合条件的块,要不存入块中
  179. }
  180. if (flag == page)
  181. {
  182. first = ready;
  183. p = ready;
  184. check(i);
  185. lack++;
  186. for (int i = 0; i < page; i++)
  187. {
  188. if (first->frequency > p->frequency)
  189. {
  190. if (p->link == NULL && first->frequency > p->frequency)
  191. {
  192. first = p;
  193. break;
  194. }
  195. first = p;
  196. }
  197. p = p->link;
  198. }
  199. first->num = first2->n;
  200. first->frequency = i;
  201. //printf("%d\n", p->num);
  202. output();
  203. }
  204. }
  205. int main()
  206. {
  207. float sum = 0;
  208. printf("请输入页框数和页数:\n");
  209. scanf("%d", &page);
  210. scanf("%d", &pagenumber);
  211. printf("page = %d, pagenumber = %d\n", page, pagenumber);
  212. input();
  213. first2 = ready2;
  214. p = ready;
  215. for (int i = 0; i < pagenumber; i++)//循环调出页
  216. {
  217. LRU(i);
  218. first = ready;
  219. flag = 0;
  220. }
  221. sum = (float)lack / pagenumber;
  222. printf("缺页率是:%0.1f%%", sum * 100);
  223. destory();
  224. return 0;
  225. }

注:*代表缺页状况,替换后的输出

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

闽ICP备14008679号