页面置换算法实验
本次实验一共用到了两个封装的类。
一个是作业的类,Block,其中的属性包括其中存入的页面的页号,和布尔类型的是否为空的属性。
另一个是pageRaplacing类,用来进行页面置换算法。
包括页面数组pages、物理块数组blocks、页面个数、物理块数、页面置换次数。
int pages[MAXPAGENUM];//页面号
Block blocks[MAXBLOCKNUM];//物理块
int pageNum;//页面个数
int blockSize;//物理块数
int replaceTime;//页面置换次数
在输入函数中输入物理块的个数、页面数和页面号的引用串。
- FIFOreplacement()
初始化,令每个块为空。设置次序队列order。
对于每一个页面,如果当前能够查找到一个非空的块,其中的页面号和当前页面的页号一样的话,将find变量置为true,否则需要将该页面加入物理块中。
如果物理块未满,找到一个空的块,将页面放入空块;如果物理块已满,将当前页面放在队列中队首位置的物理块,并且将当前的物理块号放入队列中。
queue<int> order;//次序队列
for (int i = 0; i < pageNum; i++) {
bool find = false;
for (int j = 0; j < blockSize; j++) {
if (!blocks[j].isEmpty && blocks[j].page == pages[i]) {
find = true;
break;
}
}
if (!find) {
//需要进行页面替换
bool hasEmpty = false;
for (int j = 0; j < blockSize; j++) {
if (blocks[j].isEmpty) {
blocks[j].isEmpty = false;
blocks[j].page = pages[i];
replaceTime++;
hasEmpty = true;
order.push(j);
break;
}
}
if (!hasEmpty) {
int pointer = order.front();
order.pop();
blocks[pointer].page = pages[i];
replaceTime++;
order.push(pointer);
}
}
}
- LRUreplacement()
初始化,令每个块为空。设置记录存放时间的栈sta,用STL::vector实现。
对于每一个页面,首先查找其是否在已有栈中,如果在的话,将其弹出并重新入栈,同时赋值find为true,如果没有找到,需要判断当前物理块是否已经放满。
如果未满,找到一个空的物理块,将当前页面放入;如果已满,需要将栈顶元素记录并弹出,将放置弹出的页面的物理块中的内容置换为当前页面。
需要注意的是,为了不影响对栈顶元素的查找工作,这里将页面号的入栈操作放在判断页面置换之后进行。
vector<int> sta;
for (int i = 0; i < pageNum; i++) {
bool find = false;
for (vector<int>::iterator iter = sta.begin(); iter != sta.end(); iter++) {
if ((*iter) == pages[i]) {
find = true;
sta.erase(iter);
break;
}
}
if (!find) {
//没有找到
if (sta.size() == blockSize) {
//已满
int change = sta.back();
sta.pop_back();
for (int j = 0; j < blockSize; j++) {
if (blocks[j].page == change) {
blocks[j].page = pages[i];
break;
}
}
replaceTime++;
}
else {
for (int j = 0; j < blockSize; j++) {
if (blocks[j].isEmpty) {
blocks[j].isEmpty = false;
blocks[j].page = pages[i];
replaceTime++;
break;
}
}
}
}
sta.push_back(pages[i]);
}
完整的程序代码如下:
#pragma warning (disable:4996)
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <fstream>
#include <vector>
#include <queue>
#include <stack>
#define inf 0X3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
/*
页面号引用串:
7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
4 7 0 7 1 0 1 2 1 2 6
*/
const int MAXBLOCKNUM = 10;//系统分配的物理块的个数
const int MAXPAGENUM = 30;//系统分配的物理块的个数
struct Block {
//物理块
int page;
bool isEmpty;
};
class pageReplacing {
private:
int pages[MAXPAGENUM];//页面号
Block blocks[MAXBLOCKNUM];//物理块
int pageNum;//页面个数
int blockSize;//物理块数
int replaceTime;//页面置换次数
public:
void input();
void FIFOreplacement();
void LRUreplacement();
};
void pageReplacing::input() {
cout << "请输入物理块数:";
cin >> blockSize;
cout << "请输入页面数:";
cin >> pageNum;
cout << "请输入页面号引用串:";
for (int i = 0; i < pageNum; i++) {
cin >> pages[i];
}
}
void pageReplacing::FIFOreplacement() {
for (int j = 0; j < blockSize; j++)
blocks[j].isEmpty = true;
replaceTime = 0;
queue<int> order;//次序队列
for (int i = 0; i < pageNum; i++) {
bool find = false;
for (int j = 0; j < blockSize; j++) {
if (!blocks[j].isEmpty && blocks[j].page == pages[i]) {
find = true;
break;
}
}
if (!find) {
//需要进行页面替换
bool hasEmpty = false;
for (int j = 0; j < blockSize; j++) {
if (blocks[j].isEmpty) {
blocks[j].isEmpty = false;
blocks[j].page = pages[i];
replaceTime++;
hasEmpty = true;
order.push(j);
break;
}
}
if (!hasEmpty) {
int pointer = order.front();
order.pop();
blocks[pointer].page = pages[i];
replaceTime++;
order.push(pointer);
}
}
cout << "页面" << pages[i] << ":\n";
cout << "块:\n";
for (int j = 0; j < blockSize; j++) {
if (blocks[j].isEmpty)
cout << "| " << " |\n";
else
cout << "| " << blocks[j].page << " |\n";
}
}
cout << "页面置换次数:" << replaceTime << "\n";
}
void pageReplacing::LRUreplacement() {
for (int j = 0; j < blockSize; j++)
blocks[j].isEmpty = true;
replaceTime = 0;
vector<int> sta;
for (int i = 0; i < pageNum; i++) {
bool find = false;
for (vector<int>::iterator iter = sta.begin(); iter != sta.end(); iter++) {
if ((*iter) == pages[i]) {
find = true;
sta.erase(iter);
break;
}
}
if (!find) {
//没有找到
if (sta.size() == blockSize) {
//已满
int change = sta.back();
sta.pop_back();
for (int j = 0; j < blockSize; j++) {
if (blocks[j].page == change) {
blocks[j].page = pages[i];
break;
}
}
replaceTime++;
}
else {
for (int j = 0; j < blockSize; j++) {
if (blocks[j].isEmpty) {
blocks[j].isEmpty = false;
blocks[j].page = pages[i];
replaceTime++;
break;
}
}
}
}
sta.push_back(pages[i]);
cout << "页面" << pages[i] << ":\n";
cout << "栈:\n";
for (vector<int>::iterator iter = sta.begin(); iter != sta.end(); iter++) {
cout << "| " << *iter << " |\n";
}
cout << "\n";
cout << "块:\n";
for (int j = 0; j < blockSize; j++) {
if (blocks[j].isEmpty)
cout << "| " << " |\n";
else
cout << "| " << blocks[j].page << " |\n";
}
}
cout << "页面置换次数:" << replaceTime << "\n";
}
int main() {
pageReplacing replace;
replace.input();
replace.FIFOreplacement();
replace.input();
replace.LRUreplacement();
return 0;
}