在操作系统的课上学到了页面替换算法,要想彻底理解还需要自己动手来实现,进行验证。
这里为了方便,先把page类的声明展示:
//Page.h
#pragma once
class Page
{
private:
int number;
int use_count;//未使用时间统计
public:
Page() :number(0), use_count(0)
{
}
friend class PageReplacement_FIFO_array;
friend class PageReplacement_FIFO_list;
friend class PageReplacement_LRU_count;
friend class PageReplacement_LRU_stack;
};
下面用c++程序来为各位讲解如何实现FIFO算法。
FIFO,顾名思义,就是谁先用谁先被替换,按固定顺序循环。
(一)存储方式为数组:显然我们可以用数组索引的形式,每次替换后自动加1(或从尾到头)。
//PageReplacement_FIFO_array.h
#pragma once
#include<vector>
#include"Page.h"
class PageReplacement_FIFO_array
{
private:
int page_num; //物理内存块数
bool flag;//是否缺页的标志位,这里把刚开始页面没填充满也算作缺页
int cur;//当前将要作为淘汰的页号
std::vector<Page> pages;
public:
PageReplacement_FIFO_array(int m_page_num);
/*void create();*/
void print();
bool find(int x); //查找是否已在内存物理块中
void FIFO(int x); //FIFO页面置换算法
void PageReplace(int count);
};
//PageReplacement_FIFO_array.cpp
#include "PageReplacement_FIFO_array.h"
#include <iostream>
PageReplacement_FIFO_array::PageReplacement_FIFO_array(int m_page_num)
: page_num(m_page_num), cur(0) //默认从下标是0的位置开始替换
{
pages.resize(page_num);
}
void PageReplacement_FIFO_array::print() //将每次更新后的结果输出,以便验证自己写的程序对不对
{
for (int i = 0; i < page_num; i++)
{
std::cout << pages[i].number << " ";
}
std::cout << std::endl;
}
bool PageReplacement_FIFO_array::find(int x)
{
for (auto e:pages)
{
if (e.number == x)
{
return true;
}
}
return false;
}
void PageReplacement_FIFO_array::FIFO(int x)
{
flag = true;
if (!find(x)) //必须每次先进行查找,找不到再根据我们已经设定好的位置进行替换
{
flag = false;
pages[cur].number = x;
cur = (cur + 1) % page_num;//更新下一次替换的位置
}
std::cout << "input:" << x << " ";
print();
}
void PageReplacement_FIFO_array::PageReplace(int count) //页面替换的操作
{
int random;
static int Page_Fault_count=0;
for (int i = 0; i < count; i++)
{
random = rand()%50 + 1;
FIFO(random);
if (flag == false)
{
Page_Fault_count++;
}
}
double rate = (double)(Page_Fault_count) / (double)count;//计算缺页率
std::cout << "the rate of missing pages:" << rate << std::endl;
}
(二)存储方式为链表:显然我们需要从头遍历到尾,再从尾找到头,需要循环链表,这里以stl中的list演示:
//PageReplacement_FIFO_list.h
#pragma once
#include<list>
#include"Page.h"
class PageReplacement_FIFO_list
{
private:
int page_num; //物理内存块数
bool flag;//是否缺页的标志位
std::list<Page> pages;
std::list<Page>::iterator cur ;//当前将要作为淘汰的页
public:
PageReplacement_FIFO_list(int m_page_num);
void print();
bool find(int x); //查找是否已在内存物理块中
void FIFO(int x); //FIFO页面置换算法
void PageReplace(int count);
};
//PageReplacement_FIFO_list.cpp
#include "PageReplacement_FIFO_list.h"
#include <iostream>
#include<list>
PageReplacement_FIFO_list::PageReplacement_FIFO_list(int m_page_num)
: page_num(m_page_num)
{
pages.resize(page_num);
cur = pages.begin();
}
void PageReplacement_FIFO_list::print()
{
for (auto e:pages)
{
std::cout << e.number << " ";
}
std::cout << std::endl;
}
bool PageReplacement_FIFO_list::find(int x)
{
for (auto e : pages)
{
if (e.number == x)
{
return true;
}
}
return false;
}
void PageReplacement_FIFO_list::FIFO(int x)
{
flag = true;
if (!find(x))
{
flag = false;
cur->number = x;
std::list<Page>::iterator page_end = pages.end();
page_end--;//这里是要找到链表尾,因为list的end()是最后一个元素的下一个位置
if (cur != page_end)
{
cur++;
}
else
{
cur = pages.begin();
}
}
std::cout << "input:" << x << " ";
print();
}
void PageReplacement_FIFO_list::PageReplace(int count)
{
int random;
static int Page_Fault_count = 0;
for (int i = 0; i < count; i++)
{
random = rand() % 50 + 1;
FIFO(random);
if (flag == false)
{
Page_Fault_count++;
}
}
double rate = (double)(Page_Fault_count) / (double)count;
std::cout << "the rate of missing pages:" << rate << std::endl;
}
执行结果:
//main.cpp
#include<iostream>
using namespace std;
#include"PageReplacement_FIFO_array.h"
#include"PageReplacement_FIFO_list.h"
#include<list>
void FIFO_array()
{
PageReplacement_FIFO_array pages(3);
pages.print();
pages.PageReplace(5000);
}
void FIFO_list()
{
PageReplacement_FIFO_list pages(3);
pages.print();
pages.PageReplace(5000);
}
int main()
{
FIFO_array();
FIFO_list();
return 0;
}
FIFO_array :
内存容量为3块:
内存容量为4块:
可以发现当内存容量提高后
命中率将会提高,缺页率(这里指的是概率,实际情况可能会相反)会降低。其他算法情况与之类似。
FIFO_list:
内存容量为3块:
内存容量为4块: