文章来源:神风の九_操作系统实验-CSDN博客,原创内容,转载请注明!
一、实验内容
问题描述:
设计程序模拟先进先出FIFO、最佳置换OPI和最近最久未使用LRU页面置换算法的工作过程。假设内存中分配给每个进程的最小物理块数为m,在进程运行过程中要访问的页面个数为n,页面访问序列为P1, … ,Pn,分别利用不同的页面置换算法调度进程的页面访问序列,给出页面访问序列的置换过程,计算每种算法缺页次数和缺页率。
程序要求:
1)利用先进先出FIFO、最佳置换OPI和最近最久未使用LRU三种页面置换算法模拟页面访问过程。
2)模拟三种算法的页面置换过程,给出每个页面访问时的内存分配情况。
3)输入:最小物理块数m,页面个数n,页面访问序列P1, … ,Pn,算法选择1-FIFO,2-OPI,3-LRU。
4)输出:每种算法的缺页次数和缺页率。
二、程序主要构成说明
1.判断页面是否存在内存中,遍历内存队列,如果命中,返回true,未命中返回false
2.初始化内存空间和就绪队列,设置测试集
3.FIFO算法,根据队列顺序,判断下一个页面是否命中
4.LRU算法,每次命中时,需要将内存中命中的页面移动到内存队列的尾部。
5.OPT算法,每当下一个页面到来时,都要遍历之后的页面,根据内存中已存在的页面,判断需要替换的是内存中的哪一个页面
三、完整代码
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
int input[20] = {4, 3, 2, 1, 4, 3, 5, 4, 3, 2, 1, 5, 6, 2, 3, 7, 1, 2, 6, 1};
queue<int>fifo;
queue<int>lru;
int curOpt[3] = {-1, -1, -1};
bool isopt[3] = {false, false, false};
int OPTRes[20];
int optCount = 0;
bool isExist(int index) {
int len = fifo.size();
bool flag = false;
for(int i = 0; i < len; i++) {
if(input[index] == fifo.front()) {
flag = true;
}
fifo.push(fifo.front());
fifo.pop();
}
return flag;
}
void printQueue() {
int len = fifo.size();
for(int i = 0; i < len; i++) {
cout<<fifo.front()<<" ";
fifo.push(fifo.front());
fifo.pop();
}
cout<<endl;
}
bool isLRUExist(int index) {
int len = lru.size();
bool flag = false;
int temp = 0;
for(int i = 0; i < len; i++) {
if(input[index] == lru.front()) {
//从当前位置移动到队列尾
temp = input[index];
flag = true;
lru.pop();
continue;
}
lru.push(lru.front());
lru.pop();
}
if(flag) {
lru.push(temp);
}
return flag;
}
void printLRUQueue() {
int len = lru.size();
for(int i = 0; i < len; i++) { //myqueue_size 必须是固定值
cout<<lru.front()<<" ";
lru.push(lru.front());
lru.pop();
}
cout<<endl;
}
bool isInOptQueue(int num) {
int len = 3;
bool flag = false;
for(int i = 0; i < len; i++) {
if(curOpt[i] == num) {
return true;
}
}
return flag;
}
void printCurOptQueue() {
for(int i = 0; i < 3; i++) {
cout<<curOpt[i]<<" ";
}
cout<<endl;
}
void changeOpt(int num, int index) {
int count = 0;
int temp[3];
// if(index == 18) cout<<"!!";
for(int i = index; i < 20; i++) {
for(int j = 0; j < 3; j++) {
if(count == 2) {
if(temp[0] != curOpt[0] && temp[1] != curOpt[0]) {
// cout<<"sss"<<curOpt[0]<<" "<<temp[0]<<endl;
curOpt[0] = num;
OPTRes[optCount++] = num;
return;
}
if(temp[0] != curOpt[1] && temp[1] != curOpt[1]) {
curOpt[1] = num;
OPTRes[optCount++] = num;
return;
}
if(temp[0] != curOpt[2] && temp[1] != curOpt[2]) {
curOpt[2] = num;
OPTRes[optCount++] = num;
return;
}
return;
}
if(input[i] == curOpt[j]) {
temp[count] = input[i];
count++;
}
}
}
curOpt[0] = num;
OPTRes[optCount++] = num;
}
int main() {
//FIFO算法
int len = 20;
int fifoRes[20];
int count = 0;
cout<<"FIFO算法"<<endl;
cout<<"内存中存在的页面"<<endl;
for(int i = 0; i < len; i++) {
printQueue();
if(isExist(i)) {
continue;
}
if(fifo.size() == 3) {
fifo.pop();
}
fifo.push(input[i]);
fifoRes[count++] = input[i];
}
cout<<"调入队列为:";
for(int i = 0; i < count; i++) {
cout<<fifoRes[i]<<" ";
}
cout<<endl<<"缺页率为:"<<count * 1.0 / len;
//LRU算法
int LRURes[20];
count = 0;
cout<<endl<<endl<<"LRU算法"<<endl;
cout<<"内存中存在的页面"<<endl;
for(int i = 0; i < len; i++) {
printLRUQueue();
if(isLRUExist(i)) {
continue;
}
if(lru.size() == 3) {
lru.pop();
}
lru.push(input[i]);
LRURes[count++] = input[i];
}
cout<<"调入队列为:";
for(int i = 0; i < count; i++) {
cout<<LRURes[i]<<" ";
}
cout<<endl<<"缺页率为:"<<count * 1.0 / len;
//OPT算法
cout<<endl<<endl<<"OPT算法"<<endl;
for(int i = 0; i < 3; i++) {
curOpt[i] = input[i];
OPTRes[optCount++] = input[i];
printCurOptQueue();
}
for(int i = 3; i < len; i++) {
if(i != 3) {
printCurOptQueue();
}
if(isInOptQueue(input[i])) {
continue;
}
changeOpt(input[i], i);
}
printCurOptQueue();
cout<<"调入队列为:";
for(int i = 0; i < optCount; i++) {
cout<<OPTRes[i]<<" ";
}
cout<<endl<<"缺页率为:"<<optCount * 1.0 / len<<endl;
system("pause");
return 0;
}
四、运行结果
测试数据集
1、FIFO算法
2.LRU算法
3.OPT算法
五、总结
1.FIFO算法
循环遍历页面,根据输入的队列,循环走一遍,直到都遍历完,先判断页面是否在内存中(也就是是否命中),如果命中了,则跳过,如果没有命中,则寻找内存中最早进入的页面,进行替换。
2.LRU算法
LRU和FIFO的不同点在于,LRU需要把根据命中的页面,对原先队列中的页面位置进行改变。大致流程如下,循环遍历页面走向列表,直到都遍历完,先判断页面是否在内存中(是否命中),如果在,则把内存中该页面的进入时间清0,其他页面时间增加1,如果不在,则寻找内存中最早进入的页面,进行替换,其他页面时间增加1。
3.OPT算法
由于在实际中,不能预知下一个到来的是哪一个页面,因此OPT算法不能用于实际开发,OPT算法虽然不能在实际中应用,但是可以模拟页面命中的性能。效率循环遍历页面走向列表,直到都遍历完,先判断页面是否在内存中(是否命中),如果在,则命中跳过,如果不在,则寻找内存中在后面序列中最晚使用的页面,然后进行替换。