设计程序模拟先进先出FIFO、最佳置换OPI和最近最久未使用LRU页面置换算法的工作过程。假设内存中分配给每个进程的最小物理块数为m,在进程运行过程中要访问的页面个数为n,页面访问序列为P1, … ,Pn,分别利用不同的页面置换算法调度进程的页面访问序列,给出页面访问序列的置换过程,计算每种算法缺页次数和缺页率。
程序要求:
1)利用先进先出FIFO、最佳置换OPI和最近最久未使用LRU三种页面置换算法模拟页面访问过程。
2)模拟三种算法的页面置换过程,给出每个页面访问时的内存分配情况。
3)输入:最小物理块数m,页面个数n,页面访问序列P1, … ,Pn,算法选择1-FIFO,2-OPI,3-LRU。
4)输出:每种算法的缺页次数和缺页率。
完整代码
#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdlib.h>
using namespace std;
#define MaxNumber 100
int PageOrder[MaxNumber]; //页面序列
int Simulate[MaxNumber][MaxNumber];//存放输出的数组
int PageCount[MaxNumber]; //当前内存距离下一次出现的距离
int BlockNum;//物理块数
int PageNum; //页面个数
int LackNum; //缺页数
double LackPageRate; //缺页率
bool found; //页面是否命中
int timeOfLRU[MaxNumber]; //记录物理块中各个页面最近使用时间
int memoryPage[MaxNumber]; //虚拟队列
int choose;
void input(); //输入
void initial(); //初始化物理块
void FIFO();
void OPI();
void LRU();
void chooseAlgorithm();//选择使用的算法
void output(); //输出
int main(){
input();
chooseAlgorithm();
return 0;
}
void input(){
cout<<"请输入最小物理块数:";
cin>>BlockNum;
cout<<"请输入页面个数:";
cin>>PageNum;
cout<<"请输入页面访问序列:";
for (int i=0;i<PageNum;i++)
{
cin>>PageOrder[i];
}
}
void initial(){//初始化
int i,j,k;
int z=0; //判断初始化物理块是否填满
bool found;
LackNum = BlockNum;//缺页数=物理块数+缺页次数
LackPageRate = 0.0;
for(int i = 0;i<PageNum;i++){
PageCount[i] = 0; //初始化距离
memoryPage[i] = -1; //初始化队列
}
for(int i=0;i<BlockNum;i++){
for (int j=0;j<PageNum;j++){
Simulate[i][j]=-1;//初始化
}
}
for (int i = 0;i<PageNum;i++){//初始化物理块
found = false;
timeOfLRU[i] = 0;
for (int j = 0;j<BlockNum;j++){
if (memoryPage[j] == PageOrder[i])//页面命中
{
found = true;
}
}
if (!found){ //当有新的进程进入到队列时,便计算其对应的距离
memoryPage[z] = PageOrder[i];//小于物理块数时,页面顺序进入队列
for(int j=0;j<=z;j++){
Simulate[j][i]=memoryPage[j];//保存当前序列的值
}
z++;
for (int k = 0;k<i;k++){
timeOfLRU[k]++; //之前的页面对应的时间+1
}
}
else{
timeOfLRU[i] = 0; //重新更新为0,表示最近刚刚使用
}
if(z==BlockNum){ //物理块被填满,结束循环
break;
}
}
}
void FIFO(){
cout<<"当前选择的算法:FIFO"<<endl;
initial();
int i,j,k;
int point = 0;
//分配内存
for (int i = BlockNum;i<PageNum;i++){
found = false;
for (int k = 0;k<BlockNum;k++){
if (memoryPage[k] == PageOrder[i]){ //页面命中
found = true;
}
}
if (!found){ //如果页面不在队列中,则进行相应的处理
LackNum++; //缺页数加1
memoryPage[point] = PageOrder[i];//页面替换队列中最老的
for(int j=0;j<=BlockNum;j++){
Simulate[j][i]=memoryPage[j];//保存当前序列的值
}
point++;//后移
if (point == BlockNum)//当指向队尾时后,重新指向队首
point = 0;
}
}
output();//输出物理块状态
LackPageRate = (LackNum * 1.0)/PageNum;
cout<<"缺页数:: "<<LackNum<<endl;
cout<<"缺页率:: "<<LackPageRate<<endl;
}
//最佳置换
void OPI(){
cout<<"当前选择的算法:OPI"<<endl;
int i,j,s,k,m,t;
initial();
int distance; //表示队列每个值距离下一次访问的距离
int point; //指向最长时间未被访问的下标
for(i = BlockNum;i<PageNum;i++){
found = false;
for (k = 0;k<BlockNum;k++){
if (memoryPage[k] == PageOrder[i]){ //页面命中
found = true;
}
}
if (!found){
LackNum++;
//计算当前队列每一页对应的下一次出现的距离
for (s = 0;s < BlockNum;s++){
distance = 1;
for (t = i;t<PageNum;t++){ //向后找离他最远的
if (memoryPage[s] != PageOrder[t])
distance++;
else
break;
}
PageCount[s] = distance;//当前内存距离下一次出现的距离
}
//向后比较队列内最长时间不被访问的并淘汰,置换页面
point = 0;
for (m = 1;m < BlockNum;m++){
if (PageCount[point] < PageCount[m])
point = m;
}
memoryPage[point] = PageOrder[i];
for(j=0;j<=BlockNum;j++){
Simulate[j][i]=memoryPage[j];//保存当前序列的值
}
}
}
output();
LackPageRate = (LackNum*1.0)/PageNum;
cout<<"缺页数:: "<<LackNum<<endl;
cout<<"缺页率:: "<<LackPageRate<<endl;
}
// 最长时间未被访问
void LRU(){
cout<<"当前选择的算法:LRU"<<endl;
int i,j,s,k;
initial();
int point;//指向最长时间未被访问的下标
for(i = BlockNum;i<PageNum;i++){
found = false;
for (k = 0;k<BlockNum;k++){
if (memoryPage[k] == PageOrder[i]) //页面命中
found = true;
}
if (!found){
LackNum++;
//向前比较队列内最长时间不被访问的并淘汰,置换页面
point = 0;
for(j = 1;j<BlockNum;j++){
if (timeOfLRU[point]<timeOfLRU[j])
point = j;
}
for (s = 0;s<BlockNum;s++){//其余页面对应的时间要+1
if (memoryPage[s] != memoryPage[point])
timeOfLRU[s]++;
}
memoryPage[point] = PageOrder[i];
for(j=0;j<=BlockNum;j++){
Simulate[j][i]=memoryPage[j];//保存当前序列的值
}
timeOfLRU[point] = 0;
}
else{ //负责更新当前对应页面的时间
for (s = 0;s<BlockNum;s++){//其余页面对应的时间要+1
if (memoryPage[s] != PageOrder[i])
timeOfLRU[s]++;
else
timeOfLRU[s] = 0;
}
}
}
output();
LackPageRate = (LackNum*1.0)/PageNum;
cout<<"缺页数:"<<LackNum<<endl;
cout<<"缺页率:"<<LackPageRate<<endl;
}
void chooseAlgorithm()
{
cout<<"---------------------------------"<<endl;
cout<<"请选择算法:"<<endl;
cout<<"1-先进先出页面置换算法(FIFO)"<<endl;
cout<<"2-最佳置换算法(OPI)"<<endl;
cout<<"3-最近最久未使用页面置换算法(LRU)"<<endl;
cout<<"0-结束"<<endl;
cout<<"---------------------------------"<<endl;
cin>>choose;
cout<<endl;
if (choose==1)
{
FIFO();
chooseAlgorithm();
}
else if(choose==2)
{
OPI();
chooseAlgorithm();
}
else if(choose==3){
LRU();
chooseAlgorithm();
}
else if(choose==0){
exit(0);
}
else
{
cout<<endl;
cout<<"输入错误,请重新选择:1-先进先出页面置换算法(FIFO),2-最佳置换算法(OPI),3-最近最久未使用页面置换算法(LRU),0-结束"<<endl;
chooseAlgorithm();
}
}
void output(){
int i,j;
for(i=0;i<PageNum;i++){
cout<<PageOrder[i]<<" ";
}
cout<<endl;
for(i=0;i<BlockNum;i++){
for(j=0;j<PageNum;j++){
if(Simulate[i][j]==-1){
cout<<" ";
}else{
cout<<Simulate[i][j]<<" ";
}
}
cout<<endl;
}
}
实例运行结果截图:
最小物理块数:3
页面个数:20
页面访问序列:4 3 2 1 4 3 5 4 3 2 1 5 6 2 3 7 1 2 6 1