先进先出页面置换算法(FIFO)

什么是FIFO


        该算法总是淘汰最新进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰,该算法简单,只需把一个进程已调入内存的页面按先后次序链接成一个队列,并设置一个指针,称为替换指针,使它总是指向最老的页面。但该算法与进程实际运行的规律不相适应,因为在进程中没有写页面经常被访问,比如,含有全局变量、常用函数、例程等的页面,FIFO算法并不能保证这些页面不被淘汰。


基本思想


  • 当进程访问一个页面时,会有三种情况:

    (a)有空闲的内存页,且内存中没有该页面

    (b)没有空闲的内存页,但是内存中已有该页面

    (c)没有空闲的内存页,内存中也没有该页面,要进行页面置换

  • 举例如下:

    测试用例:页面队列为:7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1;分配的内存物理块数为3。


    
    
    

  • FIFO就是寻找在内存中存在时间最久的那一个页面,将之替换出去,我们可以设置一个countOldPoint变量,初始值为0,来指示呆在内存中最久的页面;

  • 设置一个变量PRO_MEMORY来指示分配的内存物理块数。比如说,

      

  • 此时内存可用的空间已满,那么countOldPoint初始值为0,也就是开始时指示7这个页面,当内存空间满时,且要调入内存空间的页面不在此时的内存中时,则要发生替换,则将7替换出去,然后,令countOldPoint++,此时countOldPoint指示的是页面0.所以实现时,即当发生页面替换时,就会令countOldPoint++,并且令countOldPoint % PRO_MEMORY(当countOldPoint指向内存中最后一个物理块时,下一次)。这样便实现了之前所说的“替换指针”的作用。下面用图解释这段话:



    

                                   
 (1)                         (2)                        (3)                     (4)                     (5)
  
  • 从(1)状态到(2)状态,是内存调入了页面2,并把页面7替换出去,接着替换指针便指向了第二个内存物理块中存的页面;
  • 从(2)状态到(3)状态,是因为内存需要页面0,但此页面已在内存中,所以不发生页面置换,所以替换指针也不发生变化;
  • 从(3)状态到(4)状态,是内存调入了页面3,并把当前替换指针指向的页面0替换出去了,接着替换指针指向了第三个内存物理块中存的页面;
  • 从(4)状态到(5)状态,是内存调入了页面0,并把当前替换指针指向的页面1替换出去了,因为总共分配了三块物理块,所以现在替换指针便又开始指向第一个内存物理块中的页面;
  • 依次循环,执行完后面所有的页面。

总结:替换指针总是在发生页面置换的时候改变指向的内存物理块中,也就是改变了指向的页面。
 
  


源代码:

   1、工具类:Page

  
  
  1. #include"Page.h"
  2. intPage::getId()const{
  3. returnthis->id;
  4. }
  5. voidPage::setId(int id){
  6. this->id = id;
  7. }
  8. intPage::getCount()const{
  9. return count;
  10. }
  11. voidPage::inc(){
  12. count++;
  13. }
  14. voidPage::setCount(int count){
  15. this->count = count;
  16. }
  17. Page::Page(int id){
  18. this->id = id;
  19. }
  20. Page::~Page(){
  21. }


   2、核心算法


  
  
  1. #include"Page.h"
  2. #include<iostream>
  3. #include<vector>
  4. #include<iostream>
  5. #include"FIFO.h"
  6. #include<fstream>
  7. #include<conio.h>
  8. usingnamespace std;
  9. typedefvector<Page> LISTPAGE;
  10. typedefvector<int> USEPAGE;
  11. LISTPAGE pages;
  12. USEPAGE usePageNumList;
  13. ofstream ofs("F:\\coodblock\\Test\\record.txt",ios::app);
  14. void FIFO::init()
  15. {
  16. if(!ofs)return;
  17. //初始化count
  18. count =0;
  19. cout <<"请输入分配的内存块数:";
  20. cin >> PRO_MEMORY;
  21. ofs <<"请输入分配的内存块数:"<< PRO_MEMORY <<"\n";
  22. cout <<"请输入页面队列的长度:";
  23. cin >> length;
  24. cout <<"请输入页面使用列表,以空格分开:";
  25. ofs <<"请输入页面使用列表,以空格分开:";
  26. int da;
  27. for(int i =0; i < length; i++)
  28. {
  29. cin >> da;
  30. usePageNumList.push_back(da);
  31. ofs << da <<" ";
  32. }
  33. ofs <<"\n页面置换过程如下:\n";
  34. for(int j =0; j < PRO_MEMORY; j++)
  35. {
  36. Page*p =newPage(-1);
  37. pages.push_back(*p);
  38. }
  39. }
  40. /**
  41. * 显示当前内存中保留的的页面
  42. */
  43. void FIFO::display()
  44. {
  45. cout <<"当前内存保留的页面是:";
  46. ofs <<"当前内存保留的页面是:";
  47. for(int i =0; i < pages.size(); i++)
  48. {
  49. cout << pages[i].getId()<<" ";
  50. ofs << pages[i].getId()<<" ";
  51. }
  52. ofs <<"\n";
  53. cout << endl;
  54. }
  55. bool FIFO::search(int pageId)
  56. {
  57. for(int i =0; i < pages.size(); i++)
  58. {
  59. if(pages[i].getId()== pageId)
  60. returntrue;
  61. }
  62. returnfalse;
  63. }
  64. void FIFO::replace(int pageId)
  65. {
  66. //置换在内存中呆的时间最久的页面
  67. int outPageId =-1;
  68. outPageId = pages[countOldPoint].getId();
  69. pages[countOldPoint].setId(pageId);
  70. cout <<"页号ID:"<< pageId <<"正在放入内存,页号ID:"<< outPageId <<"被替换出去"<< endl;
  71. ofs <<"页号ID:"<< pageId <<"正在放入内存,页号ID:"<< outPageId <<"被替换出去\n";
  72. }
  73. void FIFO::running()
  74. {
  75. for(int i =0; i < length; i++)
  76. {
  77. countOldPoint = countOldPoint % PRO_MEMORY;
  78. int inPageId = usePageNumList[i];
  79. int key = getch();
  80. if(key==13){
  81. if(search(inPageId))
  82. {
  83. cout <<"内存中有ID为"<< inPageId <<",这个页面不能置换"<< endl;
  84. ofs <<"内存中有ID为"<< inPageId <<",这个页面不能置换\n";
  85. }
  86. elseif(count < PRO_MEMORY)//有空闲内存页
  87. {
  88. pages[count++].setId(inPageId);
  89. cout <<"页号ID:"<< inPageId <<"正在放入内存中"<< endl;
  90. ofs <<"页号ID:"<< inPageId <<"正在放入内存中\n";
  91. }
  92. else//替换
  93. {
  94. replace(inPageId);
  95. lackTime++;
  96. countOldPoint++;
  97. }
  98. display();
  99. }else{
  100. i--;
  101. cout<<"请按enter键"<<endl;
  102. }
  103. }
  104. cout <<"缺页次数为:"<< lackTime <<",缺页率为:"<<(float) lackTime /(length - PRO_MEMORY)<< endl;
  105. ofs <<"缺页次数为:"<< lackTime <<",缺页率为:"<<(float) lackTime /(length - PRO_MEMORY)<<"\n";
  106. ofs <<"============================================================";
  107. ofs.close();
  108. }




工程下载地址(包括了LRU、OPT、FIFO):

http://download.csdn.net/detail/cs9426478/9631210

假设每个页面中可存放10条指令,分配给作业的内存块数为4。 用C语言语言模拟一个作业的执行过程,该作业共有320条指令, 即它的地址空间为32页,目前它的所有页都还未调入内存。在模拟过程中,如果所访问的指令已在内存,则显示其物理地址,并转下一条指令。如果所访问的指令还未装入内存,则发生缺页,此时需要记录缺页的次数,并将相应页调入内存。如果4个内存块均已装入该作业,则需要进行页面置换,最后显示其物理地址,并转向下一条指令。在所有320条指令执行完毕后,请计算并显示作业运行过程中发生的缺页。 置换算法:请分别考虑最佳置换算法(OPT)、先进先出FIFO)算法和最近最久未使用算法(LRU)。 作业中指令的访问次序按下述原则生成: 50%的指令是顺序执行的; 25%的指令是均匀分布在前地址部分; 25%的指令是均匀分布在后地址部分; 具体的实施方法是:    在[0,319]的指令地址之间随机选取一起点m;    顺序执行下一条指令,即执行地址序号为m+1的指令;    通过随机数,跳转到前地址部分[0,m+1]中的某条指令处,其序号为m1;    顺序执行下一条指令,其地址序号为m1+1的指令;    通过随机数,跳转到后地址部分[m1+2,319]中的某条指令处,其序号为m2;    顺序执行下一条指令,其地址序号为m2+1的指令; 重复跳转到前地址部分,顺序执行,跳转到后地址部分,顺序执行的过程直至执行320条指令。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值