实验题目: 机时: 4<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> <实验二> 模拟页式虚拟存储管理地址转换和缺页中断 |
目的与任务: 虚拟存储器是指具有请求调入功能和置换功能,能从逻辑上对内存容量进行扩充的一种存储器系统。在虚拟存储器系统中,作业无需全部装入,只要装入一部分就可运行。本实验使用请求分页存储管理。建立一个页表,要访问页面时,先查页表,若当前页在内存中,直接访问,不在内存中则调入该页到内存中,同时用FIFO算法淘汰最先进入内存的页。 |
内容和要求: FIFO淘汰算法是最先使用的页面最先被淘汰。该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。该算法实现简单只需把一个进程已调入内存的页面,按先后次序链接成一个队列,并设置一个指针,称为替换指针,使它总是指向最老的页面。 先进先出(FIFO)页面置换算法,是根据页面调入内存后的使用情况进行决策的。该算法是选择在内存中驻留时间最久的页面予以淘汰。该算法赋于请求调入页面一个空间(工作集),淘汰掉最先调入的页,取而代之的是紧随它进来的页,这样就基本上实现了对最先进入内存的页面的淘汰。 |
三 .实验过程 我在程序设计过程中,只实现了页面的调入,淘汰等模拟过程,没有涉及到地址变换,所以程序中去掉了关于主存块号,磁盘上的位置等内容,程序相对简单。下面是对程序相关内容说明: 1.定义页数和内存块数 #define m 5 //m表示页数 #define n 3 //n表示物理块数 2.页表与物理块 由于页表里的内容我只保留了两项,一个时页号,一个是标志,所以我将页表演变位一个一维数组 int PageTable[m]; 数组PageTable大小为m,分别存储对应页面的状态,表示该页面是否在内存中。状态位 =1表示该页在物理块中,=0表示不在内存中,默认处置为0。如PageTable[0]=1表示页面1在物理块中,PageTable[2]=0表示表示页面3不在物理块中。 用一个一维数组表示n个物理块中的内容 int Block[n]; 数组中数值表示对应物理块中装入的页的编号。数组初始值都为0,表示没有装入页。如Block[3]={3,1,2},则表示物理块中当前装入页为第1,2,3页。 3.访问页面 访问页面通过一个访问函数实现 void Visit(int); //访问函数 访问过程中会遇到三种情况 A. 访问页时没有命中,且内存未装满,产生缺页中断,直接调入访问页 需要进行的操作有:产生缺页中断,中断次数加1,将访问页调入内存,修改 此页的状态, interrupt++; //缺页中断次数加1 PageTable[x-1]=1; //修改状态位 Block=x; //页x调入物理块
B. 访问页时命中 此时直接访问
C. 访问页时内存已装满,且没有命中,产生缺页中断,调入该页至内存,淘汰最先进入的页 需要进行的操作有:产生缺页中断,中断次数加1,淘汰最先进入的页(即淘汰页指针所指的页)并修改淘汰页的状态位,调入访问页到物理块并修改调入页的状态位,最后还要修改淘汰页指针指向下一次需要淘汰的页 interrupt++; //缺页中断次数加1 PageTable[Block[k]-1]=0; //页Block[k]被淘汰,状态位修改为 0 Block[k]=x; //页x调入物理块 PageTable[x-1]=1; //页x状态位修改为 1 k=(k+1)%n; //修改下次被淘汰页指针 4.主函数 在主函数中输入页面走向,将其存入进程访问序列process[20]进程访问序列,然后依次访问即可。 |
四 .实验结果 参照课本126页表可以看出结果十分正确。 |
试验程序:
#include<iostream.h>
#include<iomanip.h>
#define m 5 //m表示页数
#define n 3 //n表示物理块数
float interrupt="0".; //产生缺页中断的次数
int k="0"; //指向最先进入内存的页,即被淘汰的页
int PageTable[m]; //定义页表,总共m页,数组中数值是状态位 =1表示该页在内存中,=0表示不在内存中,默认处置为0
int Block[n]; //定义物理块,总共n个,数组中数值表示对应物理块中装入的页的编号
int process[20]; //进程访问序列
int number="1"; //用于标志访问次数
void Visit(int); //访问函数
/********************************************************************************
主函数
********************************************************************************/
void main (void)
{
int input;
cout<<"某进程共有"<<m<<"页,请输入进程访问序列(范围:1-"<<m<<",用0表示结束):\n";
cin>>input;
for(int length="0";input!=0;length++) //将输入序列存入process数组,长度为length
{
process[length]=input;
cin>>input;
}
for(int j="0";j<length;j++)
Visit(process[j]); //依次访问页process[j]
cout<<"共"<<length<<"次访问,产生"<<interrupt<<"次缺页中断,缺页率为 "<<interrupt/length<<"\n";
}
/********************************************************************************
访问函数
********************************************************************************/
void Visit(int x)
{
int i,j;
cout<<setw(2)<<number<<": 访问页"<<x<<" "; //第number次访问,访问页x
for(i=0;i<n;i++)
{
if(Block==0) //访问页x时没有命中,且内存未装满,产生缺页中断,直接调入访问页
{
interrupt++; //缺页中断次数加1
PageTable[x-1]=1; //修改状态位
Block=x; //页x调入物理块
cout<<"缺页中断 内存未满 调入页"<<x<<" 物理块内的页为 ";
for(j=0;j<=i;j++)cout<<Block[j]<<" "; //输出物理块内的页号
cout<<"\n";
break;
}
if(PageTable[x-1]==1) //访问页x时命中
{
cout<<"命中 物理块内的页为 ";
for(j=0;j<n && Block[j]!=0;j++)cout<<Block[j]<<" "; //输出物理块内的页号
cout<<"\n";
break;
}
}
if(i==n) //访问页x时内存已装满,且没有命中,产生缺页中断,调入该页至内存,淘汰最先进入的页
{
cout<<"缺页中断 淘汰页"<<Block[k]<<" 调入页"<<x<<" 物理块内的页为 ";
interrupt++; //缺页中断次数加1
PageTable[Block[k]-1]=0; //页Block[k]被淘汰,状态位修改为 0
Block[k]=x; //页x调入物理块
PageTable[x-1]=1; //页x状态位修改为 1
k=(k+1)%n; //修改下次被淘汰页指针
for(j=0;j<n;j++)cout<<Block[j]<<" "; //输出物理块内的页号
cout<<"\n";
}
number++; //访问次数加1
}
文章评论(0条评论)
登录后参与讨论