【操作系统】 页面置换算法的c++实现

页面置换算法实验

本次实验一共用到了两个封装的类。

一个是作业的类,Block,其中的属性包括其中存入的页面的页号,和布尔类型的是否为空的属性。

另一个是pageRaplacing类,用来进行页面置换算法。
包括页面数组pages、物理块数组blocks、页面个数、物理块数、页面置换次数。

int pages[MAXPAGENUM];//页面号
Block blocks[MAXBLOCKNUM];//物理块
int pageNum;//页面个数
int blockSize;//物理块数
int replaceTime;//页面置换次数

在输入函数中输入物理块的个数、页面数和页面号的引用串。

  1. 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);
		}
	}
}
  1. 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;
}
  • 2
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是常见的三种操作系统页面置换算法C++ 代码实现: 1. 先进先出(FIFO)页面置换算法: ```cpp #include <iostream> #include <queue> using namespace std; int main() { queue<int> fifo; // 存放页面的队列 int page_num, frame_num, page_fault = 0; // 页面数、帧数、页面失效次数 cin >> page_num >> frame_num; int* pages = new int[page_num]; // 存放页面的数组 for (int i = 0; i < page_num; ++i) { cin >> pages[i]; } for (int i = 0; i < page_num; ++i) { int page = pages[i]; if (fifo.size() < frame_num) { // 如果队列未满,直接加入队尾 fifo.push(page); ++page_fault; } else { // 如果队列已满,弹出队头,再加入队尾 int front_page = fifo.front(); if (front_page != page) { fifo.pop(); fifo.push(page); ++page_fault; } } } cout << "FIFO: " << page_fault << endl; delete[] pages; return 0; } ``` 2. 最近最久未使用(LRU)页面置换算法: ```cpp #include <iostream> #include <list> #include <unordered_map> using namespace std; int main() { list<int> lru; // 存放页面的双向链表 unordered_map<int, list<int>::iterator> map; // 存放页面和其在链表中的迭代器 int page_num, frame_num, page_fault = 0; // 页面数、帧数、页面失效次数 cin >> page_num >> frame_num; int* pages = new int[page_num]; // 存放页面的数组 for (int i = 0; i < page_num; ++i) { cin >> pages[i]; } for (int i = 0; i < page_num; ++i) { int page = pages[i]; auto iter = map.find(page); if (iter != map.end()) { // 如果页面已在链表中,先删除再插入到链表尾部 lru.erase(iter->second); map.erase(iter); } if (lru.size() == frame_num) { // 如果链表已满,删除链表头部(最近最久未使用的页面) int front_page = lru.front(); lru.pop_front(); map.erase(front_page); } // 将新页面插入链表尾部,并在 map 中记录迭代器 lru.push_back(page); map[page] = --lru.end(); ++page_fault; } cout << "LRU: " << page_fault << endl; delete[] pages; return 0; } ``` 3. 时钟页面置换算法: ```cpp #include <iostream> #include <vector> using namespace std; int main() { vector<int> clock; // 存放页面的数组 vector<bool> ref; // 存放页面的引用位 int page_num, frame_num, page_fault = 0; // 页面数、帧数、页面失效次数 cin >> page_num >> frame_num; int* pages = new int[page_num]; // 存放页面的数组 for (int i = 0; i < page_num; ++i) { cin >> pages[i]; } for (int i = 0; i < page_num; ++i) { int page = pages[i]; bool found = false; for (int j = 0; j < clock.size(); ++j) { if (clock[j] == page) { // 如果页面已在数组中,将其引用位设置为 true ref[j] = true; found = true; break; } } if (!found) { // 如果页面不在数组中,寻找第一个引用位为 false 的页面 while (true) { if (!ref[0]) { // 如果找到了,将其替换为新页面 clock[0] = page; ref[0] = true; break; } else { // 如果没找到,将所有页面的引用位都设为 false ref[0] = false; clock.push_back(clock[0]); ref.push_back(false); clock.erase(clock.begin()); ref.erase(ref.begin()); } } ++page_fault; } } cout << "Clock: " << page_fault << endl; delete[] pages; return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值