页表置换实验

实验要求

  • 程序可以指定进程所分配的页框数量,可以仿真随机产生页面访问序列(rand),页面访问序列的最大页面编号可指定,伪随机数种子可设定(srand()),页面序列长度可设定
    • A:采用伪随机数发生器产生不小于20次页面访问的序列,统计缺页率
    • B: 特别指定如下设定:3个页框,最大逻辑页号为7,20个页面访问序列7 0 1 2 0 3 0 4 2 3 0 3 2 5 4 3 6 5 3 2的仿真
  • 打印输出内存置换情况,包括当前页框中页面情况,每个页面访问是否在内存中,页面置换情况等。

代码

#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <time.h>
#define MAX1 5000 // 序列最长为5000
#define MAX2 100 // 最多100个页框
using namespace std;

int sequence_rand[MAX1]; // 伪随机序列
int sequence[20] = { 7,0,1,2,0,3,0,4,2,3,0,3,2,5,4,3,6,5,3,2}; // 自定义的伪随机序列
int page[MAX2][MAX1]; // 页表
char page_missing[MAX1]; // 缺页中断数组
int num; // 页框数量
int maximum; // 最大页面编号
int length; // 页面序列长度
char option; // 选择A内容还是B内容
double page_fault_rate; // 缺页率
int count_alive[MAX2]; // 计算页面存在的时间

// 输入函数
void input() {
	cout << "请输入页框数量:";
	cin >> num;
	cout << "请输入页面访问序列的最大页面编号:";
	cin >> maximum;
	cout << "请输入页面序列长度:";
	cin >> length;
	// 生成随机数
	srand((unsigned)time(NULL));
	for (int i = 0; i < length; i++) {
		sequence_rand[i] = rand() % (maximum + 1); 
	}
}

// 显示页面序列
void dispaly(int *p ,int length) {
	cout << "\n页面访问序列为:" << "  ";
	for (int i = 0; i < length; i++) {
		cout << *(p + i) << "  ";
	}
	cout << endl;
}

// FIFO算法
void FIFO(int *p) {
	int most = -1; // 用于判断最先到达的页
	int index; // 最先到达的页的索引
	int flag = 0; // 判断能否找到页
	// 遍历sequence
	for (int k = 0; k < length; k++) {
		for (int j = k; j < length; j++) {
			// 遍历页框
			if (j < num) {
				for (int i = 0; i < num; i++) {
					if (k == 0) {
						page[i][j] = *(p + k);
						count_alive[i] += 1;
						page_missing[k] = 'Y';
						break;
					}
					// 若不为空
					if (page[i][j - 1] != -1) {
						page[i][j] = page[i][j - 1];
						count_alive[i] += 1;
					}
					// 若为空
					else
					{
						page[i][j] = *(p + k);
						page_missing[k] = 'Y';
						count_alive[i] = 1;
						break;
					}
				}
			}
			else{
				// 能找到
				for (int a = 0; a < num; a++) {
					if( *(p + k) == page[a][j - 1]){
						page_missing[k] = 'N';
						flag = 1;
						break;
					}
				}
				if (flag == 1) {
					for (int a = 0; a < num; a++) {
						page[a][j] = page[a][j - 1]; // 复制前一列的数据
						count_alive[a] += 1;
					}
					flag = 0;
					break;
				}
				// 不能找到,需要进行页表置换
				if (flag == 0) {
					page_missing[k] = 'Y';
					for (int a = 0; a < num; a++) {
						if (count_alive[a] > most) {
							most = count_alive[a];
							index = a;
						}
					}
					most = -1;
					for (int a = 0; a < num; a++) {
						if (a == index) { // 替换
							page[a][j] = *(p + k);
							count_alive[a] = 1;
						}
						else {
							page[a][j] = page[a][j - 1];
							count_alive[a] += 1;
						}
					}
				}
			}
			break;
		}
	}
}

// 计算缺页率
void calculate() {
	int n = 0;
	for (int i = 0; i < length; i++) {
		if (page_missing[i] == 'Y') {
			n += 1;
		}
	}
	page_fault_rate = n * 1.0 / length;
	cout << "缺页率:" << page_fault_rate << "\n" << endl;
}

// 输出页表详情
void output() {
	dispaly(sequence, length);
	for (int i = 0; i < num; i++) {
		if (i == 0) {
			cout << "页框" << i + 1 << ":\t\t  ";
		}
		else if (i == 1) {
			cout << "页框" << i + 1 << ":\t\t ";
		}
		else {
			cout << "页框" << i + 1 << ":\t\t";
		}
		for (int j = 0; j < length; j++) {
			cout << page[i][j] << "  ";
		}
		cout << endl;
	}
	cout << "缺页中断:\t  ";
	for (int i = 0; i < length; i++) {
		cout << page_missing[i] << "  ";
	}
	cout << endl;
}

// 重置函数
void reset() {
	// 生成二维全-1数组
	for (int i = 0; i < num; i++) {
		fill(page[i], page[i] + length, -1);
	}
	// 计数器全0
	fill(count_alive, count_alive + num, 0); 
}

// LRU算法
void LRU(int* p) {
	int longer = -1; // 用于判断待得最久的页
	int index; // 待得最久的页的索引
	int flag = 0; // 判断能否找到页
	// 遍历sequence
	for (int k = 0; k < length; k++) {
		for (int j = k; j < length; j++) {
			// 遍历页框
			if (j < num) {
				for (int i = 0; i < num; i++) {
					if (k == 0) {
						page[i][j] = *(p + k);
						count_alive[i] += 1;
						page_missing[k] = 'Y';
						break;
					}
					// 若不为空
					if (page[i][j - 1] != -1) {
						page[i][j] = page[i][j - 1];
						count_alive[i] += 1;
					}
					// 若为空
					else
					{
						page[i][j] = *(p + k);
						page_missing[k] = 'Y';
						count_alive[i] = 1;
						break;
					}
				}
			}
			else {
				// 能找到
				for (int a = 0; a < num; a++) {
					count_alive[a] += 1;
					if (*(p + k) == page[a][j - 1]) {
						page_missing[k] = 'N';
						index = a;
						flag = 1;
						break;
					}
				}
				if (flag == 1) {
					for (int a = 0; a < num; a++) {
						page[a][j] = page[a][j - 1]; // 复制前一列的数据
						count_alive[a] += 1;
					}
					count_alive[index] = 1;
					flag = 0;
					break;
				}
				// 不能找到,需要进行页表置换
				if (flag == 0) {
					page_missing[k] = 'Y';
					for (int a = 0; a < num; a++) {
						if (count_alive[a] > longer) {
							longer = count_alive[a];
							index = a;
						}
					}
					longer = -1;
					for (int a = 0; a < num; a++) {
						if (a == index) { // 替换
							page[a][j] = *(p + k);
							count_alive[a] = 1;
						}
						else {
							page[a][j] = page[a][j - 1];
							count_alive[a] += 1;
						}
					}
				}
			}
			break;
		}
	}
}

// 输出函数
void Output() {
	output();
	calculate();
}

int main() {
	while (true) {
		cout << "请选择要测试 A or B 序列:";
		cin >> option;
		if (option == 'A' || option == 'a') {
			input();
			reset();
			dispaly(sequence_rand, length);
			cout << "\nFIFO算法:" << endl;
			FIFO(sequence_rand);
			calculate();
			cout << "\nLRU算法:" << endl;
			reset();
			LRU(sequence_rand);
			calculate();
		}
		else if (option == 'B' || option == 'b') {
			num = 3;
			length = 20;
			reset();
			cout << "\nFIFO算法:" << endl;
			FIFO(sequence);
			Output();
			cout << "\nLRU算法:" << endl;
			reset();
			LRU(sequence);
			Output();
		}
		else {
			break;
		}
	}
	return 0;
}

运行结果

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值