什么是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)状态,是内存调入了页面2,并把页面7替换出去,接着替换指针便指向了第二个内存物理块中存的页面;
- 从(2)状态到(3)状态,是因为内存需要页面0,但此页面已在内存中,所以不发生页面置换,所以替换指针也不发生变化;
- 从(3)状态到(4)状态,是内存调入了页面3,并把当前替换指针指向的页面0替换出去了,接着替换指针指向了第三个内存物理块中存的页面;
- 从(4)状态到(5)状态,是内存调入了页面0,并把当前替换指针指向的页面1替换出去了,因为总共分配了三块物理块,所以现在替换指针便又开始指向第一个内存物理块中的页面;
- 依次循环,执行完后面所有的页面。
源代码:
1、工具类:Page
#include"Page.h"intPage::getId()const{returnthis->id;}voidPage::setId(int id){this->id = id;}intPage::getCount()const{return count;}voidPage::inc(){count++;}voidPage::setCount(int count){this->count = count;}Page::Page(int id){this->id = id;}Page::~Page(){}
2、核心算法
#include"Page.h"#include<iostream>#include<vector>#include<iostream>#include"FIFO.h"#include<fstream>#include<conio.h>usingnamespace std;typedefvector<Page> LISTPAGE;typedefvector<int> USEPAGE;LISTPAGE pages;USEPAGE usePageNumList;ofstream ofs("F:\\coodblock\\Test\\record.txt",ios::app);void FIFO::init(){if(!ofs)return;//初始化countcount =0;cout <<"请输入分配的内存块数:";cin >> PRO_MEMORY;ofs <<"请输入分配的内存块数:"<< PRO_MEMORY <<"\n";cout <<"请输入页面队列的长度:";cin >> length;cout <<"请输入页面使用列表,以空格分开:";ofs <<"请输入页面使用列表,以空格分开:";int da;for(int i =0; i < length; i++){cin >> da;usePageNumList.push_back(da);ofs << da <<" ";}ofs <<"\n页面置换过程如下:\n";for(int j =0; j < PRO_MEMORY; j++){Page*p =newPage(-1);pages.push_back(*p);}}/*** 显示当前内存中保留的的页面*/void FIFO::display(){cout <<"当前内存保留的页面是:";ofs <<"当前内存保留的页面是:";for(int i =0; i < pages.size(); i++){cout << pages[i].getId()<<" ";ofs << pages[i].getId()<<" ";}ofs <<"\n";cout << endl;}bool FIFO::search(int pageId){for(int i =0; i < pages.size(); i++){if(pages[i].getId()== pageId)returntrue;}returnfalse;}void FIFO::replace(int pageId){//置换在内存中呆的时间最久的页面int outPageId =-1;outPageId = pages[countOldPoint].getId();pages[countOldPoint].setId(pageId);cout <<"页号ID:"<< pageId <<"正在放入内存,页号ID:"<< outPageId <<"被替换出去"<< endl;ofs <<"页号ID:"<< pageId <<"正在放入内存,页号ID:"<< outPageId <<"被替换出去\n";}void FIFO::running(){for(int i =0; i < length; i++){countOldPoint = countOldPoint % PRO_MEMORY;int inPageId = usePageNumList[i];int key = getch();if(key==13){if(search(inPageId)){cout <<"内存中有ID为"<< inPageId <<",这个页面不能置换"<< endl;ofs <<"内存中有ID为"<< inPageId <<",这个页面不能置换\n";}elseif(count < PRO_MEMORY)//有空闲内存页{pages[count++].setId(inPageId);cout <<"页号ID:"<< inPageId <<"正在放入内存中"<< endl;ofs <<"页号ID:"<< inPageId <<"正在放入内存中\n";}else//替换{replace(inPageId);lackTime++;countOldPoint++;}display();}else{i--;cout<<"请按enter键"<<endl;}}cout <<"缺页次数为:"<< lackTime <<",缺页率为:"<<(float) lackTime /(length - PRO_MEMORY)<< endl;ofs <<"缺页次数为:"<< lackTime <<",缺页率为:"<<(float) lackTime /(length - PRO_MEMORY)<<"\n";ofs <<"============================================================";ofs.close();}
本文详细介绍了FIFO页面置换算法的基本原理及其实现过程,通过具体实例展示了算法的工作流程,包括页面置换的发生条件和替换指针的作用。
1069

被折叠的 条评论
为什么被折叠?



