实验要求
- 程序可以指定进程所分配的页框数量,可以仿真随机产生页面访问序列(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;
}
运行结果