#include<iostream.h>
#include<stdio.h>
#include<iomanip.h>
const int Max = 10; //最大块号
const int Size = 30; //最长页号
static int count=0; //缺页数
static int d=0; //自增数
void Init(int block[],int n) //存储块的初始化
{
int i;
for(i=0;i<n;i++)
{
block[i] = -1;
}
}
void creat(int page[],int m) //访问页面的字符串的输入函数
{
int i;
for(i=0;i<m;i++)
{
cin>>page[i];
}
}
void Out(int a[],int aa) //块或者页的输出
{
int i;
for(i=0;i<aa;i++)
cout<<setw(2)<<a[i];
cout<<endl;
}
/*判断块是否已满*/
int isFull(int block[],int n)
{
int index=0; //记录剩余块数
for(int i=0;i<n;i++)
{
if(block[i] == -1)
index++ ;
}
if(index>0)
return 0; //有剩余
else
return 1; //1代表块满了
}
/*查看块中是否存在这个页号*/
int exist(int block[],int page[],int n,int i)
{
for(int x=0;x<n;x++)
{ if(page[i]==block[x])
return x; //x 表示块中有这个页号 返回地址
}
return -1; //-1 表示块中没有这个页号
}
/*LRU中访问页进入存储块 (m是块的序列 i是即将进入块的序号)*/
void pushIn(int block[],int page[],int n,int i)
{
if(exist(block,page,n,i)==-1) //块中没有这个页号
{
count++;
cout<<"缺页产生"<<count<<"次"<<endl;
int k=page[i]; //保存写入当前的页号
if(isFull(block,n)==0) //块剩余的时候读入 page
{
//当插入页的数目不够n-1个时把数组初始位置置为-1,否则不变
for(int j=count;j>0;j--) //把新来的页放着第一位,原来的全部往后挪一位
block[j] =block[j-1];
block[0] = k;
}
else //块满了
{
for(int i=n-1;i>0;i--)
block[i]=block[i-1]; //把block[n-1]踢出 即低下最久未使用的
block[0]=k; //把page[i]写入块中 放在数组首位
}
}
else //块中存在这个页号 exist(block,page,n,i)!=0
{
cout<<"块中已经有这个页号了!"<<endl;
if(isFull(block,n)==0) //有剩余块的时候
{
int flag;
flag=block[exist(block,page,n,i)]; //保存当前的页号值
if(exist(block,page,n,i)>0)
{
for(int j=exist(block,page,n,i);j>1;j--)
block[j]=block[j-1];
block[1]=flag;
}
}
else //块中页面满了
{
int fflag;
fflag=block[exist(block,page,n,i)];
for(int k=exist(block,page,n,i);k>0;k--)
{
block[k]=block[k-1];
}
block[0]=fflag;
}
}
}
/*FIFO中访问页进入存储块 (m是块的序列 i是即将进入块的序号)*/
void isIn(int block[],int page[],int n,int i)
{
if(exist(block,page,n,i)==-1) //块中没有这个页号
{
count++;
cout<<"缺页产生"<<count<<"次"<<endl;
int k=page[i]; //保存写入当前的页号
if(isFull(block,n)==0) //块剩余的时候读入 page
{
block[d] = k;
d++;
}
else //块满了
{
for(int i=0;i<n;i++)
{
if(i<n-1)
{
block[i]=block[i+1]; //把block[0]踢出
}
else
block[i]=k; //把page[i]写入块中
}
}
}
else
cout<<"块中已经有这个页号了!"<<endl;
}
void FIFO(int page[],int block[],int m,int n) //页数为m页 块数为n块
{
cout<<"调用的页号总序列为:";
Out(page,m);
cout<<"块序列为:";
Out(block,n);
for(int i=0;i<m;i++)
{
cout<<"第"<<i+1<<"个页序列 "<<page[i]<<" 入块!";
isIn(block,page,n,i);
cout<<"块序列为:";
Out(block,n);
}
}
void LRU(int page[],int block[],int m,int n) //页数为m页 块数为n块
{
cout<<"调用的页号总序列为:";
Out(page,m);
cout<<"块序列为:";
Out(block,n);
for(int i=0;i<m;i++)
{
cout<<"第"<<i+1<<"个页序列 "<<page[i]<<" 入块!";
pushIn(block,page,n,i);
cout<<"块序列为:";
Out(block,n);
}
}
void main()
{
int m,n;
int block[Max],page[Size];
double rate1,rate2; //FIFO算法和LRU算法的缺页率
cout<<setw(40)<<"存储管理"<<endl;
cout<<"请输入内存块数m(m<=6):";
while(1)
{
cin>>n;
if(n<0||n>6)
{
cout<<"输入错误!请重新输入!";
cout<<"请重新输入内存块数:";
}
else break;
}
Init(block,n);
cout<<"请输入总页面数m(m<=30):";
cin>>m;
cout<<endl;
cout<<"请输入页面号引用串:";
creat(page,m);
cout<<"算法过程如下:"<<endl;
int choose;
cout<<"*********************************"<<endl;
cout<<"请选择序号 1:FIFO算法 2:LRU算法"<<endl;
cin>>choose;
switch(choose)
{
case 1:
cout<<setw(40)<<"这是FIFO算法!"<<endl;
FIFO(page,block,m,n);
rate1=((double)count)/((double)m);
cout<<"FIFO的缺页率为:"<<rate1<<endl;
break;
case 2:
cout<<setw(40)<<"这是LRU算法!"<<endl;
LRU(page,block,m,n);
rate2=((double)count)/((double)m);
cout<<"FIFO的缺页率为:"<<rate2<<endl;
break;
default:
break;
}
}
程序说明:
FIFO算法解析
利用定义两个数组:页号数组和存储块数组。
首先,查询页号在块中是否存在。
如果不存在,则入块,并判断块空和满的情况下分别将页号插入到块中。否则告知已经存在。
LRU算法解析
可利用一个特殊的数组来保存当前使用的各个页面的页面号。每当进程访问某页面时,便将该页面的页面号从数组中移除,将它放入数组的首位。因此,数组的首位始终是最新被访问页面的编号,而数组的最后一位则是最近最久未使用的页面号。