#include<iostream>
#include<string.h>
#include<iomanip>
using namespace std;
int N;//物理块的个数
int M;//页面序列中页面的个数
int block[N];//物理块数组
int page[M];//页面序列数组
int FIFO();
int LRU();
int OPT();
int in(int p);//对于新到来的页面检查是否在内存中,若在,则返回页面下标,不在则返回-1
int lastest_be_used(int j);//在当前物理页面中将最晚被使用的页面下标
int find_max_unused();//对各物理块的未使用次数进行比较,返回最久未被使用的页面下标
void add();//将每个物理块的未使用次数+1
//int find_least_used(int j);
int unused[N]={0};//记录各物理块的未使用次数
int main()
{
cout<<"请输入页面个数:";
cin>>M;
cout<<endl;
cout<<"请输入页面序列"<<endl;
for(int i=0;i<M;i++)
{
cin>>page[i];
}
cout<<"请输入物理块数:";
cin>>N;
cout<<endl;
cout<<"OPT缺页中断次数:"<<OPT()<<endl;
cout<<"***********************************"<<endl;
cout<<"LRU缺页中断次数:"<<LRU()<<endl;
cout<<"***********************************"<<endl;
cout<<"FIFO缺页中断次数:"<<FIFO()<<endl;
cout<<"***********************************"<<endl;
return 0;
}
int in(int p)//对于新到来的页面检查是否在内存中
{
for(int i=0;i<N;i++)
if(p==block[i])
return i;
return -1;
}
int FIFO()
{
memset(block,-1,sizeof(int)*N);
int index=0;//block[i],当i加到N后重置为0,相当于一个循环链表,i不断移动指向新的表头
int page_lack=0;
cout<<" "<<"\t";
for(int j=0;j<N;j++)
cout<<"页"<<j<<"\t";
cout<<endl;
for(int j=0;j<M;j++)
{
//cout<<"是否再内存中: "<<in(page[j])<<endl;
if(in(page[j])==-1)
{
if(index>=N) index=0;
block[index++]=page[j];
page_lack++;
}
cout<<page[j]<<setw(2)<<"\t";
for(int k=0;k<N;k++)
cout<<block[k]<<"\t";
cout<<endl;
}
return page_lack;
}
int find_least_used(int j)
{
int used_num[N]={0};//记录当前物理页面中各页面之前被使用过的次数
int temp;
int min_used;//在此时的物理页面中,使用次数最少的物理页面下标
for(int i=0;i<j;i++)
{
for(int k=0;k<N;k++)
{
if(page[i]==block[k])
used_num[k]++;
}
}
temp=used_num[0];
min_used=0;
for(int i=1;i<N;i++)
{
if(temp>used_num[i])
{
temp=used_num[i];
min_used=i;
}
}
return min_used;
}
int find_max_unused()//对各物理块的未使用次数进行比较,返回最久未被使用的页面下标
{
int max_unused=0;
int temp=unused[0];
for(int i=1;i<N;i++)
{
if(temp<unused[i])
{
temp=unused[i];
max_unused=i;
}
}
return max_unused;
}
void add()//将每个物理块的未使用次数+1
{
for(int i=0;i<N;i++)
unused[i]++;
}
int LRU()
{
memset(block,-1,sizeof(int)*N);
int index=0;//被替换的页面下标
int page_lack=0;
cout<<" "<<"\t";
for(int j=0;j<N;j++)
cout<<"页"<<j<<"\t";
cout<<endl;
int page_num;
for(int i=0;i<M;i++)
{
//cout<<"是否再内存中: "<<in(page[i])<<endl;
page_num=in(page[i]);//page[i]是否在内存中,在则返回页面号,不在则返回-1
if(page_num==-1)
{
//cout<<"index,block[index]: "<<index<<","<<block[index]<<endl;
if(index<N&&block[index]==-1)//存在空闲块
{
// cout<<"有空闲块"<<endl;
block[index]=page[i];
index++;
page_lack++;//缺页次数+1
for(int j=0;j<=index;j++)
unused[j]++;//为被使用次数+1
}
else{
// cout<<"无空闲块"<<endl;
// index=find_least_used(i);
index=find_max_unused();
add();
unused[index]=0;//先将所有unused次数+1,然后将新到来的页面的unused次数置0
block[index]=page[i];
page_lack++;//缺页次数+1
}
}
else
{
add();
unused[page_num]=0;//若在内存中,则先将所有unused次数+1,再将命中的页面unused次数置0
}
cout<<page[i]<<setw(2)<<"\t";
for(int k=0;k<N;k++)
cout<<block[k]<<"\t";
cout<<endl;
}
return page_lack;
}
int lastest_be_used(int j)//在当前物理页面中将最晚被使用的页面下标
{
int last_used=0;
int temp;
int num[N];
for(int i=0;i<N;i++)
num[i]=100;
int flag[N]={0};//保证是第一次将被使用
for(int i=j;i<M;i++)
{
for(int k=0;k<N;k++)
{
if(block[k]==page[i]&&!flag[k])
{
num[k]=i-j;
flag[k]=1;
}
}
}
cout<<"num数组"<<endl;
for(int i=0;i<N;i++)
cout<<num[i]<<" ";
cout<<endl;
temp=num[0];
last_used=0;
for(int i=1;i<N;i++)
{
if(temp<num[i])
{
temp=num[i];
last_used=i;
}
}
return last_used;
}
int OPT()
{
memset(block,-1,sizeof(int)*N);
int page_lack=0;
int index=0;
cout<<" "<<"\t";
for(int j=0;j<N;j++)
cout<<"页"<<j<<"\t";
cout<<endl;
for(int i=0;i<M;i++)
{
// cout<<"是否再内存中: "<<in(page[i])<<endl;
// cout<<"index,block[index]: "<<index<<","<<block[index]<<endl;
if(in(page[i])==-1)
{
// cout<<"不在内存中"<<endl;
if(index<N&&block[index]==-1)
{
// cout<<"有空闲块"<<endl;
block[index]=page[i];
index++;
page_lack++;//缺页次数+1
}
else{
// cout<<"无空闲块"<<endl;
index=lastest_be_used(i);//最晚将被使用的页面
block[index]=page[i];
page_lack++;//缺页次数+1
}
}
cout<<page[i]<<setw(2)<<"\t";
for(int k=0;k<N;k++)
cout<<block[k]<<"\t";
cout<<endl;
}
return page_lack;
}
操作系统实验--页面替换算法(FIFO,OPT,LRU)
最新推荐文章于 2022-04-15 23:17:14 发布