当前位置:   article > 正文

操作系统:页面置换算法_页面置换算法代码

页面置换算法代码

(一)实验目的

     编写一个程序,实现第九章所述的FIFO、OPT和LRU页面置换算法。

(二)实验要求及内容

  1. 首先,生成一个随机的页面引用串,其中页码的范围为0~9。
  2. 将这个随机页面引用串应用到每个算法,记录每个算法引起的缺页次数,列出每次页面置换的换出页序号,计算缺页率
  3. 系统分配给用户的页面帧的数量可选:3~7,具体分配策略可自行定义。
  4. 假设采用请求分页(按需调页)。

(三)代码:直接运行可能会报错,如果报错,可参考(五)的解决方案

  1. #include <stdio.h>
  2. #include<time.h>
  3. #include <stdlib.h>
  4. //初始化队列
  5. void initializeList(int list[], int number) {
  6. for (int i = 0; i < number; i++) {
  7. list[i] = -1;
  8. }
  9. }
  10. //展示队列状态
  11. void showList(int list[], int number) {
  12. for (int i = 0; i < number; i++) {
  13. printf("%2d", list[i]);
  14. }
  15. printf("\n");
  16. }
  17. //展示当前内存状态
  18. void showMemoryList(int list[], int phyBlockNum) {
  19. for (int i = 0; i < phyBlockNum; i++) {
  20. if (list[i] == -1) {
  21. break;
  22. }
  23. printf(" |%d|", list[i]);
  24. }
  25. printf("\n");
  26. }
  27. void informationCount(int missingCount, int replaceCount, int pageNum) {
  28. printf("\n缺页次数:%d 缺页率:%d/%d\n", missingCount, missingCount, pageNum);
  29. double result = (double)(pageNum - missingCount) / (double)pageNum;
  30. printf("置换次数:%d 命中率:%.2f\n\n", replaceCount, result);
  31. }
  32. //找到该页面下次要访问的位置
  33. int getNextPosition(int currentPage, int currentPosition, int strList[], int pageNum) {
  34. for (int i = currentPosition + 1; i < pageNum; i++) {
  35. if (strList[i] == currentPage) {
  36. return i;
  37. }
  38. }
  39. return 100;
  40. }
  41. //最佳置换算法
  42. void replacePageByOPT(int memoryList[], int phyBlockNum, int strList[], int pageNum) {
  43. //置换次数
  44. int replaceCount = 0;
  45. //缺页次数
  46. int missingCount = 0;
  47. //记录在内存的物理块的下一次访问位置
  48. int nextPosition[7];
  49. //初始化
  50. initializeList(nextPosition, phyBlockNum);
  51. //记录当前页面的访问情况: 0 未访问
  52. int isVisited;
  53. for (int i = 0; i < pageNum; i++) {
  54. isVisited = 0;
  55. //判断是否需要置换->内存已满且需要访问的页面不在内存中
  56. for (int j = 0; j < phyBlockNum; j++) {
  57. if (memoryList[j] == strList[i]) {
  58. //该页面已经存在内存中
  59. //记录下一次访问它的位置
  60. nextPosition[j] = getNextPosition(memoryList[j], i, strList, pageNum);
  61. //修改访问情况
  62. isVisited = 1;
  63. //展示
  64. printf("%d\n", strList[i]);
  65. break;
  66. }
  67. if (memoryList[j] == -1) {
  68. //页面不在内存中且内存未满->直接存入
  69. memoryList[j] = strList[i];
  70. nextPosition[j] = getNextPosition(memoryList[j], i, strList, pageNum);
  71. missingCount++;
  72. //修改访问情况
  73. isVisited = 1;
  74. //展示
  75. printf("%d\n\n", strList[i]);
  76. showMemoryList(memoryList, phyBlockNum);
  77. printf("\n\n");
  78. break;
  79. }
  80. }
  81. if (!isVisited) {
  82. //当前页面还没访问过
  83. //内存已满且当前访问不在内存中->进行置换
  84. //1.寻找到最晚才被访问到的页面
  85. int max = 0;
  86. for (int k = 1; k < phyBlockNum; k++) {
  87. if (nextPosition[max] < nextPosition[k]) {
  88. max = k;
  89. }
  90. }
  91. //2.将该位置的页面换出
  92. printf("被置换的页面号是:%d\n", memoryList[max]);//打印被调出内存的页号
  93. memoryList[max] = strList[i];
  94. nextPosition[max] = getNextPosition(memoryList[max], i, strList, pageNum);
  95. missingCount++;
  96. replaceCount++;
  97. //展示
  98. printf("%d\n", strList[i]);
  99. showMemoryList(memoryList, phyBlockNum);
  100. printf("\n\n");
  101. }
  102. }
  103. informationCount(missingCount, replaceCount, pageNum);
  104. }
  105. //先进先出置换算法
  106. void replacePageByFIFO(int memoryList[], int phyBlockNum, int strList[], int pageNum) {
  107. //置换次数
  108. int replaceCount = 0;
  109. //缺页次数
  110. int missingCount = 0;
  111. //记录当前最早进入内存的下标
  112. int pointer = 0;
  113. //记录当前页面的访问情况: 0 未访问
  114. int isVisited = 0;
  115. for (int i = 0; i < pageNum; i++) {
  116. isVisited = 0;
  117. //判断是否需要置换->内存已满且需要访问的页面不在内存中
  118. for (int j = 0; j < phyBlockNum; j++) {
  119. if (memoryList[j] == strList[i]) {
  120. //该页面已经存在内存中
  121. //修改访问情况
  122. isVisited = 1;
  123. //修改访问时间
  124. //展示
  125. printf("%d\n\n", strList[i]);
  126. break;
  127. }
  128. if (memoryList[j] == -1) {
  129. //页面不在内存中且内存未满->直接存入
  130. memoryList[j] = strList[i];
  131. //修改访问情况
  132. isVisited = 1;
  133. missingCount++;
  134. //展示
  135. printf("%d\n", strList[i]);
  136. showMemoryList(memoryList, phyBlockNum);
  137. printf("\n\n");
  138. break;
  139. }
  140. }
  141. if (!isVisited) {
  142. //当前页面还未被访问过->需要进行页面置换
  143. //直接把这个页面存到所记录的下标中
  144. printf("被置换的页面号是:%d\n", memoryList[pointer]);//打印被调出内存的页号
  145. memoryList[pointer] = strList[i];
  146. //下标指向下一个
  147. pointer++;
  148. //如果到了最后一个,将下标归零
  149. if (pointer > phyBlockNum - 1) {
  150. pointer = 0;
  151. }
  152. missingCount++;
  153. replaceCount++;
  154. //展示
  155. printf("%d\n", strList[i]);
  156. showMemoryList(memoryList, phyBlockNum);
  157. printf("\n\n");
  158. }
  159. }
  160. informationCount(missingCount, replaceCount, pageNum);
  161. }
  162. //最近最久未使用置换算法
  163. void replacePageByLRU(int memoryList[], int phyNum, int strList[], int pageNum) {
  164. //置换次数
  165. int replaceCount = 0;
  166. //缺页次数
  167. int missingCount = 0;
  168. //记录内存中最近一次访问至今的时间
  169. int timeRecord[7];
  170. //初始化
  171. initializeList(timeRecord, phyNum);
  172. //记录当前页面的访问情况: 0 未访问
  173. int isVisited = 0;
  174. //记录已经在内存中的页面数量
  175. int pageCount = 0;
  176. for (int i = 0; i < pageNum; i++) {
  177. isVisited = 0;
  178. //时间加一
  179. for (int p = 0; p < pageCount; p++) {
  180. if (memoryList[p] != -1) {
  181. timeRecord[p] ++;
  182. }
  183. }
  184. //是否需要置换
  185. for (int j = 0; j < phyNum; j++) {
  186. if (memoryList[j] != -1) {
  187. timeRecord[j] ++;
  188. }
  189. if (memoryList[j] == strList[i]) {
  190. //该页面已经存在内存中
  191. //修改访问情况
  192. isVisited = 1;
  193. //重置访问时间
  194. timeRecord[j] = -1;
  195. //展示
  196. printf("%d\n\n", strList[i]);
  197. break;
  198. }
  199. if (memoryList[j] == -1) {
  200. //页面不在内存中且内存未满->直接存入
  201. memoryList[j] = strList[i];
  202. pageCount++;
  203. //修改访问情况
  204. isVisited = 1;
  205. //修改访问时间
  206. timeRecord[j] ++;
  207. missingCount++;
  208. //展示
  209. printf("%d\n", strList[i]);
  210. showMemoryList(memoryList, phyNum);
  211. printf("\n\n");
  212. break;
  213. }
  214. }
  215. if (!isVisited) {
  216. //需要置换
  217. //1.遍历时间记录表,寻找最久未访问的页面所在的内存下标
  218. int max = 0;
  219. for (int k = 0; k < phyNum; k++) {
  220. if (timeRecord[max] < timeRecord[k]) {
  221. max = k;
  222. }
  223. }
  224. printf("被置换的页面号是:%d\n", memoryList[max]);//打印被调出内存的页号
  225. //2.将该位置的页面换出
  226. memoryList[max] = strList[i];
  227. timeRecord[max] = -1;
  228. missingCount++;
  229. replaceCount++;
  230. //展示
  231. printf("%d\n", strList[i]);
  232. showMemoryList(memoryList, phyNum);
  233. printf("\n\n");
  234. }
  235. }
  236. informationCount(missingCount, replaceCount, pageNum);
  237. }
  238. int main(int argc, const char* argv[]) {
  239. //物理块的数量
  240. int phyBlockNum;
  241. printf("请输入物理块数量:\n");
  242. scanf("%d", &phyBlockNum);
  243. //生成内存队列
  244. int memoryList[7];
  245. //初始化内存状态
  246. initializeList(memoryList, phyBlockNum);//未使用的内存块标记为-1;
  247. //showMemoryList(memoryList,phyBlockNum);
  248. //页面数量
  249. int pageNum;
  250. printf("请输入要访问的页面总数:\n");
  251. scanf("%d", &pageNum);
  252. //保存页面号引用串
  253. int pageNumStrList[100];
  254. int a;
  255. srand((unsigned)time(NULL));
  256. for (int i = 0; i < pageNum; i++) {
  257. a = rand() % 10;
  258. pageNumStrList[i] = a;
  259. }
  260. int chose;
  261. while (1) {
  262. printf("请选择所需的置换算法:\n");
  263. printf("1.OPT 2.FIFO 3.LRU 4.退出\n");
  264. printf("你选择的置换算法是:", pageNum);
  265. scanf("%d", &chose);
  266. printf("\n");
  267. switch (chose) {
  268. case 1:
  269. printf("生成的%d个页面号:\n", pageNum);
  270. showList(pageNumStrList, pageNum);
  271. replacePageByOPT(memoryList, phyBlockNum, pageNumStrList, pageNum);
  272. //重新初始化内存
  273. initializeList(memoryList, phyBlockNum);
  274. break;
  275. case 2:
  276. printf("生成的%d个页面号:\n", pageNum);
  277. showList(pageNumStrList, pageNum);
  278. replacePageByFIFO(memoryList, phyBlockNum, pageNumStrList, pageNum);
  279. //重新初始化内存
  280. initializeList(memoryList, phyBlockNum);
  281. break;
  282. case 3:
  283. printf("生成的%d个页面号:\n", pageNum);
  284. showList(pageNumStrList, pageNum);
  285. replacePageByLRU(memoryList, phyBlockNum, pageNumStrList, pageNum);
  286. //重新初始化内存
  287. initializeList(memoryList, phyBlockNum);
  288. break;
  289. default:
  290. return 0;
  291. break;
  292. }
  293. }
  294. return 0;
  295. }

(四)实验截图

 

(五)温馨提示:直接将代码放在visual studio运行可能发生以下错误:

解决方案:

1)右击当前代码文件--->>属性 

2)C/C++  ----->> 常规------>>双击“SDL检查”后面的文本框,使其改变为“否”------->>"确定"

 3)做好以上修改,就可正常运行代码

仅供参考,如有不足,请指出!

 

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

闽ICP备14008679号