• 目的要求:
• 通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解。熟悉虚存管理的各种页面淘汰算法。
• 设计一个请求页式存储管理方案。并编写模拟程序实现之。产生一个需要访问的指令地址流。它是一系列需要访问的指令的虚拟地址。
• 页面淘汰算法采用时钟页面淘汰算法,并且在淘汰一页时,只将该页在页表中抹去。而不再判断它是否被改写过,也不将它写回到辅存。
实现思想
• 模拟时钟算法,但由于无法在时钟中断时对R位进行清0,因此,近似的规则是:每访问一个页面,则将此页面的R位置1,表示刚刚访问过,不应被置换,而内存中其余各页的R值均置为0
实现步骤
• 指定合适的页面尺寸;
• 指定内存页表的最大长度,并对页表进行初始化;
• 输入一个需要访问的指令虚拟地址;
• 每访问一个地址时,首先要计算该地址所在的页的页号,然后查页表,判断该页是否在主存——如果该页已在主存,则打印页表情况;
• 如果该页不在主存且页表未满,则调入一页并打印页表情况;
• 如果该页不在主存且主存已满,则按时钟页面淘汰算法淘汰一页后调入所需的页,打印页表情况;
• 逐个地址访问,直到所有地址访问完毕。
实现代码:
#include <string>
#include <cstdlib>
#include <iostream>
using namespace std;
struct Page{ //一个页表项
bool R; //0或1
int page; //存放页号
Page *next;
};
//默认为4
Page* InitTable(int MaxPage=4){
Page* head = new Page;
head->page = -1;
head->R = false;
head->next = NULL;
//要算上头结点
for(int i=0; i<MaxPage-1; i++){
Page *p = new Page;
p->R = false;
p->page = -1; //初始设置为-1
p->next = head->next;
head->next = p;
}
Page *p = head;
while(p->next!=NULL){
p = p->next;
}
p->next = head; //将链表尾部和头部连接起来
return head;
}
//打印页表情况
void PrintRAM(Page* Head)
{
cout<<"当前页表情况:"<<endl;
cout<<"存放的页\t\tR"<<endl;
Page* p = Head;
do{
cout<<p->page<<"\t\t\t"<<p->R<<endl; //如果当前页面非空闲 打印存放的页
p = p->next;
}while(p!=Head);
return ;
}
int main(void)
{
Page* Head = InitTable();
PrintRAM(Head);
Page* replace = Head; //指向要被淘汰的页表
//页表有四页 0 1 2 3 地址输进来就先 % 4096
cout<<"页面大小为4096B,物理页帧数为4页,虚拟地址空间大小为8页."<<endl;
int address;
int page;
cout<<"请输入虚拟地址(输入-1退出):"<<endl;
cin>>address;
while(address!=-1 && address>=0 && address<32768){ //8页即地址最大为 32767
cout<<"输入的虚拟地址为:"<<address<<endl;
page = address/4096;
cout<<"该地址所对应的页号为:"<<page<<endl;
//得到页号 应该去遍历 看看是否在内存中 不在则添加到内存中
Page* p = Head;
int i;
for(i=0; i<4; i++){
if(p->page == page){
cout<<"页面"<<page<<"在内存中\n";
p->R = true;
//将其他的r置为0
p = p->next;
for(int i=0; i<3; i++){
p->R = false;
p = p->next;
}
PrintRAM(Head); //打印页表情况
break;
}
else{
p = p->next;
}
} //遍历一遍后 没发现在内存中 那就发生缺页中断
if(i==4){ //发生缺页中断 使用时钟页面淘汰算法 来替换
bool done = false; //用来判断是否已经置换
cout<<"该页不在内存中!"<<endl;
p = Head;
do{ //查找是否有空闲页
if(p->page==-1){
cout<<"当前内存中有空闲页,将目标页装入内存"<<endl;
p->page = page;
p->R = 1;
done = true;
PrintRAM(Head); //打印页表情况
break;
}
p=p->next;
}while(p!=Head);
//如果没有空闲页 定位到R位为0的页表上 如果都为1就会循环一遍,然后到达最初位置
if(!done){
while(replace->R!=0){
replace->R = 0;
replace = replace->next;
}
//如果R位为1,说明刚被访问过,则置为0,指针指向下一位
cout<<"当前内存没有空闲页,页面"<<replace->page<<"被淘汰"<<endl;
replace->R = 1;
replace->page = page; //替换
PrintRAM(Head);
}
}
cout<<"请输入虚拟地址(输入-1退出):"<<endl;
cin>>address;
}
}