在之前系列的博客中介绍了页面调度算法的原理:
    https://www.cnblogs.com/wkfvawl/p/11700301.html#_label2_3
    这里编写代码模拟一些页面调度算法的实现。

    (1)最佳淘汰算法——OPT(Optimal)
    这是Belady贝莱迪于1966年提出的一种理论上的算法。该算法每次都淘汰以后
    永不使用的,或者过最长的时间后才会被访问的页面。显然,采用这种算法会保证最低的缺页率,但它是无法实现的,因为它必须知道页面“将来”的访问情况。不过,该算法仍有一定意义,可作为衡量其他算法优劣的一个标准。
    (2)先进先出淘汰算法——FIFO
    这是最早出现的淘汰算法。
    总是淘汰最先进入内存的页面。它实现简单,只需把进程中已调入内存的页面,按先后次序链成一个队列,并设置一个所谓的替换指针,使它总是指向内存中最老的页面。
    (3) 最近最久未使用算法——(LRU, Least Recently Used)
    根据页面调入内存后的使用情况,选择内存中最久未使用的页面被置换。这是局部性原理的合理近似,性能接近最佳算法。
    OPT算法使用页面将要被访问的时间,LRU算法使用页面最后一次被访问的时间。二者唯一的差别是:OPT是向前看的,而LRU是向后看的。

    1. #include<cstdio>
    2. #include<cstring>
    3. #include<algorithm>
    4. using namespace std;
    5. int N;//进程虚页数
    6. int M;//内存块个数
    7. int page[100];//进程虚页
    8. int block[100];//内存块
    9. int weight[100];//当前内存块在后面出现的次数
    10. int success;//命中次数
    11. int fail;//未命中次数
    12. void FIFO()
    13. {
    14. int i,j;
    15. int flag;
    16. int pos=0;
    17. int success=0;
    18. int fail=0;
    19. for(i=0; i<N; i++)
    20. {
    21. flag =0;
    22. for(j=1; j<=M; j++)
    23. {
    24. if(page[i]==block[j])//命中
    25. {
    26. flag=1;
    27. success++;
    28. pos--;
    29. break;
    30. }
    31. }
    32. if(flag==0)
    33. {
    34. fail++;
    35. block[pos%M+1]=page[i];
    36. }
    37. pos++;
    38. for(j=1; j<=M; j++)
    39. {
    40. printf("%d ",block[j]);
    41. }
    42. printf("\n");
    43. }
    44. printf("命中次数为:%d\n",success);
    45. printf("未命中次数为:%d\n",fail);
    46. }
    47. void OPT()
    48. {
    49. int i,j,k;
    50. int flag;
    51. int success=0;
    52. int fail=0;
    53. int needReplace;
    54. for(i=0; i<N; i++)
    55. {
    56. flag=0;
    57. for(j=1; j<=M; j++)
    58. {
    59. if(page[i]==block[j])//命中
    60. {
    61. flag=1;
    62. success++;
    63. }
    64. }
    65. if(flag==0)//未命中
    66. {
    67. fail++;
    68. for(j=1; j<=M; j++) //若内存块未满,先将内存块填满
    69. {
    70. if(block[j]==0)
    71. {
    72. block[j]=page[i];
    73. break;
    74. }
    75. }
    76. int minCnt=100;
    77. memset(weight,0,sizeof(weight));
    78. if(j>M)//若内存块已满,需要进行调度
    79. {
    80. for(k=i+1; k<N; k++) //向后
    81. {
    82. for(j=1; j<=M; j++)
    83. {
    84. if(block[j]==page[k])
    85. {
    86. weight[j]=N-k;//越靠近,权值越大
    87. break;
    88. }
    89. }
    90. }
    91. for(j=1; j<=M; j++) //找权值最小的那一个
    92. {
    93. if(weight[j]<=minCnt)
    94. {
    95. minCnt=weight[j];
    96. needReplace=j;
    97. }
    98. }
    99. block[needReplace]=page[i];//替换掉权值最小的
    100. }
    101. }
    102. for(j=1; j<=M; j++)
    103. {
    104. printf("%d ",block[j]);
    105. }
    106. printf("\n");
    107. }
    108. printf("命中次数为:%d\n",success);
    109. printf("未命中次数为:%d\n",fail);
    110. }
    111. void LRU()
    112. {
    113. int i,j;
    114. int flag;
    115. int success=0;
    116. int fail=0;
    117. int needReplace;
    118. for(i=0; i<N; i++)
    119. {
    120. flag=0;
    121. for(j=1; j<=M; j++)
    122. {
    123. if(page[i]==block[j])//命中
    124. {
    125. flag=1;
    126. success++;
    127. }
    128. }
    129. if(flag==0)//未命中
    130. {
    131. fail++;
    132. for(j=1; j<=M; j++) //现将内存块填满
    133. {
    134. if(block[j]==0)
    135. {
    136. block[j]=page[i];
    137. break;
    138. }
    139. }
    140. if(j>M)//内存块已满,需要进行调度
    141. {
    142. //向前找,需要替换的页面为i-M
    143. needReplace=page[i-M];
    144. for(j=1; j<=M; j++)
    145. {
    146. if(block[j]==needReplace)//找到后替换掉
    147. {
    148. block[j]=page[i];
    149. break;
    150. }
    151. }
    152. }
    153. }
    154. for(j=1; j<=M; j++)
    155. {
    156. printf("%d ",block[j]);
    157. }
    158. printf("\n");
    159. }
    160. printf("命中次数为:%d\n",success);
    161. printf("未命中次数为:%d\n",fail);
    162. }
    163. int main()
    164. {
    165. printf("请输入进程执行时页面访问个数:\n");
    166. scanf("%d",&N);
    167. printf("请输入空闲内存块的个数:\n");
    168. scanf("%d",&M);
    169. printf("请输入进程执行时页面访问次序:\n");
    170. memset(page,0,sizeof(page));
    171. memset(block,0,sizeof(block));
    172. int i;
    173. int needReplace;
    174. for(i=0; i<N; i++)
    175. {
    176. scanf("%d",&page[i]);
    177. }
    178. printf("采用最佳淘汰算法OPT:\n");
    179. OPT();
    180. memset(block,0,sizeof(block));
    181. printf("采用先进先出淘汰算法FIFO:\n");
    182. FIFO();
    183. memset(block,0,sizeof(block));
    184. printf("采用最近最久未使用淘汰算法LRU:\n");
    185. LRU();
    186. return 0;
    187. }
    188. /*
    189. 12
    190. 3
    191. 2
    192. 3
    193. 2
    194. 1
    195. 5
    196. 2
    197. 4
    198. 5
    199. 3
    200. 2
    201. 5
    202. 2
    203. */