编写一个C程序,模拟LRU(最近最久未使用)页面置换算法,要求实现如下功能:
a) 随机生成长度1000的页面访问序列(每个页面的取值为1-20);
b) 内存中的物理块数为10;
c) 每次缺页且没有空闲块的时候输出被调出的页面值;
d) 计算总的缺页率;
#include<stdio.h>
#include<stdlib.h>
#define N 1000
int page[N]; //存放页面访问序列
int mc[10]; //memory capacity内存容量 ,并初始化为0
void pageflow()//随机生成长度为1000的页面访问序列,页号取值在1~20之间
{
printf("\n在1-20之间产生的1000个页面访问序列如下:\n");
for(int i=0;i<1000;i++)
{
page[i]=1+rand()%21;
printf("%3d ",page[i]);
if((i+1)%25==0) printf("\n"); //每行输出10个数
}
}
int LRU(int capacity)
{
int j,x,y,m;
int sum=0; //内存中已经分配的个数
int exist=0; //不发生缺页次数
int flag; //标志是否缺页 flag=0缺页 flag=1不缺页
int ep;
mc[0]=page[0];
printf(" %2d加入 \t",page[0]);
for(m=0;m<capacity;m++){
printf("%2d ",mc[m]);
} //输出当前内存块的存储情况
printf("\n");
sum+=1;
for(j=1;j<1000;j++)//对每一个页面访问进行处理
{
flag=0;
for(y=1;y<=sum;y++) //将需要访问的页面与内存中已有的页面进行比较,判断这个页面访问是否缺页
if(mc[y]==page[j]) {
exist++;//不发生缺页次数+1
flag=1;
printf(" %2d命中 \t",page[j]);
for(m=1;m<=capacity;m++) //输出当前内存块的存储情况
printf("%2d ",mc[m]);
printf("\n");
break;}
//没命中
if(flag==0)
{
if(sum<capacity) //还有空块
{for(x=1;x<=capacity;x++) //查找内存块中第一个空块
if(mc[x]==-1) {
mc[x]=page[j];
sum++;
printf(" %2d加入 \t",page[j]);
for(m=1;m<=capacity;m++) //输出当前内存块的存储情况
printf("%2d ",mc[m]);
printf("\n");
break;}
}
else if(sum>=capacity)//缺页且没有空块
{
int t;
int far = j-1;//最近使用时间最远的页号,初始值为当前的前面一条
int a,b;
for(b=capacity;b>=1;b--) //找最近最少使用的页
for(a=j-1;a>=0;a--)//对于内存中每一个页面,从后往前查阅访问记录
{
if(mc[b]==page[a])
{
if(a>=far)
break;
if(a<far)
{
far=a;
break;
}
}
}
for(a=1;a<=capacity;a++) //找最近最少使用的页号所在数组的下标
{
if(mc[a]==page[far])
{
ep=a;
break;
}
}
t=mc[ep];//被调出的页面值
mc[ep]=page[j];
printf(" %2d加入%2d调出\t",page[j],t);
for(m=1;m<=capacity;m++) //输出当前内存块的存储情况
printf("%2d ",mc[m]);
printf("\n");
}
}
}
printf("\n命中次数=%d\n缺页率=%lf",exist,1.0-(exist/1000.0));
}
int main()
{
int capacity = 10;
printf("\n随机生成的页地址流:\n");
pageflow();
printf("\n\n\n\t\t最近最少使用算法(LRU):\n\n");
for(int i=0;i<10;i++) {
mc[i]=-1;
} //给内存数组赋初值
LRU(capacity);
return 0;
}
运行效果: