采用多道程序思想设计一个程序,模拟页存储管理地址变换的过程,可采用FIFO、LRU、LFU、OPT四页面置换算法。基本要求如下:
(1)需要建立访问页表线程、访问快表线程、缺页中断处理线程、访问内存线程等,协同这些线程模拟完成地址变换的过程。
(2)输入一个逻辑页面访问序列和随机产生逻辑页面访问序列,分别由四个算法完成页面置换;
(3)能够设定驻留内存页面的个数、内存的存取时间、缺页中断的时间、快表的时间,并提供合理省缺值,可以暂停和继续系统的执行;
(4)能够设定页号序列中逻辑页面个数和范围;
(5)能够设定有快表和没有快表的运行模式;
(6)提供良好图形界面,同时能够展示四个算法运行的结果;
(7) 给出每种页面置换算法每个页面的存取时间;
(8) 能够将每次的实验输入和实验结果存储起来,随时可查询;
(9) 完成多次不同设置的实验,总结实验数据,看看能得出什么结论。
#include <stdio.h>
#include <stdlib.h>
/*全局变量*/
int mSIZE; /*物理块数*/
int pSIZE; /*页面号引用串个数*/
static int memery[10]={0}; /*物理块中的页号*/
static int page[100]={0}; /*页面号引用串*/
static int temp[100][10]={0}; /*辅助数组*/
/*置换算法函数*/
void FIFO();
void LRU();
void OPT();
/*辅助函数*/
void print(unsigned int t);
void designBy();
void download();
void mDelay(unsigned int Delay);
/*主函数*/
void main()
{
int i,k,code;
system("color 0A");
designBy();
printf("┃请按任意键进行初始化操作... ┃\n");
printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
printf(" >>>");
getch();
system("cls");
system("color 0B");
printf("请输入物理块的个数(M<=10):");
scanf("%d",&mSIZE);
printf("请输入页面号引用串的个数(P<=100):");
scanf("%d",&pSIZE);
puts("请依次输入页面号引用串(连续输入,无需隔开):");
for(i=0;i<pSIZE;i++)
scanf("%1d",&page[i]);
download();
system("cls");
system("color 0E");
do{
puts("输入的页面号引用串为:");
for(k=0;k<=(pSIZE-1)/20;k++)
{
for(i=20*k;(i<pSIZE)&&(i<20*(k+1));i++)
{
if(((i+1)%20==0)||(((i+1)%20)&&(i==pSIZE-1)))
printf("%d\n",page[i]);
else
printf("%d ",page[i]);
}
}
printf("* * * * * * * * * * * * * * * * * * * * * * *\n");
printf("* 请选择页面置换算法:\t\t\t *\n");
printf("* ----------------------------------------- *\n");
printf("* 1.先进先出(FIFO) 2.最近最久未使用(LRU) *\n");
printf("* 3.最佳(OPT) 4.退出 *\n");
printf("* * * * * * * * * * * * * * * * * * * * * * *\n");
printf("请选择操作:[ ]\b\b");
scanf("%d",&code);
switch(code)
{
case 1:
FIFO();
break;
case 2:
LRU();
break;
case 3:
OPT();
break;
case 4:
system("cls");
system("color 0A");
designBy(); /*显示设计者信息后退出*/
printf("┃谢谢使用页面置换算法演示器! 正版授权 ㊣┃\n");
printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
exit(0);
default:
printf("输入错误,请重新输入:");
}
printf("按任意键重新选择置换算法:>>>");
getch();
system("cls");
}while (code!=4);
getch();
}
/*载入数据*/
void download()
{
int i;
system("color 0D");
printf("╔════════════╗\n");
printf("║正在载入数据,请稍候 !!!║\n");
printf("╚════════════╝\n");
printf("Loading...\n");
printf(" O");
for(i=0;i<51;i++)
printf("\b");
for(i=0;i<50;i++)
{
mDelay((pSIZE+mSIZE)/2);
printf(">");
}
printf("\nFinish.\n载入成功,按任意键进入置换算法选择界面:>>>");
getch();
}
/*设置延迟*/
void mDelay(unsigned int Delay)
{
unsigned int i;
for(;Delay>0;Delay--)
{
for(i=0;i<124;i++)
{
printf(" \b");
}
}
}
/*显示设计者信息*/
void designBy()
{
printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
printf("┃㊣ 课题三:页面置换算法 ㊣┃\n");
printf("┃ 学号:081001117 ┃\n");
printf("┃ 姓名:邢磊 <Visual C++ 6.0>┃\n");
printf("┣━━━━━━━━━━━━━━━━━━━━━━━━━┫\n");
}
void print(unsigned int t)
{
int i,j,k,l;
int flag;
for(k=0;k<=(pSIZE-1)/20;k++)
{
for(i=20*k;(i<pSIZE)&&(i<20*(k+1));i++)
{
if(((i+1)%20==0)||(((i+1)%20)&&(i==pSIZE-1)))
printf("%d\n",page[i]);
else
printf("%d ",page[i]);
}
for(j=0;j<mSIZE;j++)
{
for(i=20*k;(i<mSIZE+20*k)&&(i<pSIZE);i++)
{
if(i>=j)
printf(" |%d|",temp[i][j]);
else
printf(" | |");
}
for(i=mSIZE+20*k;(i<pSIZE)&&(i<20*(k+1));i++)
{
for(flag=0,l=0;l<mSIZE;l++)
if(temp[i][l]==temp[i-1][l])
flag++;
if(flag==mSIZE)/*页面在物理块中*/
printf(" ");
else
printf(" |%d|",temp[i][j]);
}
/*每行显示20个*/
if(i%20==0)
continue;
printf("\n");
}
}
printf("----------------------------------------\n");
printf("缺页次数:%d\t\t",t+mSIZE);
printf("缺页率:%d/%d\n",t+mSIZE,pSIZE);
printf("置换次数:%d\t\t",t);
printf("访问命中率:%d%%\n",(pSIZE-(t+mSIZE))*100/pSIZE);
printf("----------------------------------------\n");
}
/*计算过程延迟*/
void compute()
{
int i;
printf("正在进行相关计算,请稍候");
for(i=1;i<20;i++)
{
mDelay(15);
if(i%4==0)
printf("\b\b\b\b\b\b \b\b\b\b\b\b");
else
printf("Θ");
}
for(i=0;i++<30;printf("\b"));
for(i=0;i++<30;printf(" "));
for(i=0;i++<30;printf("\b"));
}
/*先进先出页面置换算法*/
void FIFO()
{
int memery[10]={0};
int time[10]={0}; /*记录进入物理块的时间*/
int i,j,k,m;
int max=0; /*记录换出页*/
int count=0; /*记录置换次数*/
/*前mSIZE个数直接放入*/
for(i=0;i<mSIZE;i++)
{
memery[i]=page[i];
time[i]=i;
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
for(i=mSIZE;i<pSIZE;i++)
{
/*判断新页面号是否在物理块中*/
for(j=0,k=0;j<mSIZE;j++)
{
if(memery[j]!=page[i])
k++;
}
if(k==mSIZE) /*如果不在物理块中*/
{
count++;
/*计算换出页*/
max=time[0]<time[1]?0:1;
for(m=2;m<mSIZE;m++)
if(time[m]<time[max])
max=m;
memery[max]=page[i];
time[max]=i; /*记录该页进入物理块的时间*/
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
else
{
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
}
compute();
print(count);
}
/*最近最久未使用置换算法*/
void LRU()
{
int memery[10]={0};
int flag[10]={0}; /*记录页面的访问时间*/
int i,j,k,m;
int max=0; /*记录换出页*/
int count=0; /*记录置换次数*/
/*前mSIZE个数直接放入*/
for(i=0;i<mSIZE;i++)
{
memery[i]=page[i];
flag[i]=i;
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
for(i=mSIZE;i<pSIZE;i++)
{
/*判断新页面号是否在物理块中*/
for(j=0,k=0;j<mSIZE;j++)
{
if(memery[j]!=page[i])
k++;
else
flag[j]=i; /*刷新该页的访问时间*/
}
if(k==mSIZE) /*如果不在物理块中*/
{
count++;
/*计算换出页*/
max=flag[0]<flag[1]?0:1;
for(m=2;m<mSIZE;m++)
if(flag[m]<flag[max])
max=m;
memery[max]=page[i];
flag[max]=i; /*记录该页的访问时间*/
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
else
{
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
}
compute();
print(count);
}
/*最佳置换算法*/
void OPT()
{
int memery[10]={0};
int next[10]={0}; /*记录下一次访问时间*/
int i,j,k,l,m;
int max; /*记录换出页*/
int count=0; /*记录置换次数*/
/*前mSIZE个数直接放入*/
for(i=0;i<mSIZE;i++)
{
memery[i]=page[i];
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
for(i=mSIZE;i<pSIZE;i++)
{
/*判断新页面号是否在物理块中*/
for(j=0,k=0;j<mSIZE;j++)
{
if(memery[j]!=page[i])
k++;
}
if(k==mSIZE) /*如果不在物理块中*/
{
count++;
/*得到物理快中各页下一次访问时间*/
for(m=0;m<mSIZE;m++)
{
for(l=i+1;l<pSIZE;l++)
if(memery[m]==page[l])
break;
next[m]=l;
}
/*计算换出页*/
max=next[0]>=next[1]?0:1;
for(m=2;m<mSIZE;m++)
if(next[m]>next[max])
max=m;
/*下一次访问时间都为pSIZE,则置换物理块中第一个*/
memery[max]=page[i];
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
else {
for(j=0;j<mSIZE;j++)
temp[i][j]=memery[j];
}
}
compute();
print(count);
}
完整实验报告下载地址
我上传到资料里面有 。