一、实验目的与要求
本实验的目的是通过请求页式存储管理中的页面调度算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理中的页面调度算法,并会计算缺页中断率。
二、实验内容
1、实验预备内容
掌握请求页是存储管理中的页面调度算法.缺页中断率的计算。通过一指令序列。
2、实验内容
设定一个指令序列,设定内存中分配的页数。模拟指令序列的执行,将指令流转换为地址流,指出该地址是否在内存,如果不在内存输出淘汰的页和调入的页;如果在内存输出其页号和页内地址,并计算缺页中断率。
使用的页面淘汰算法为先进先出的算法。
即模拟页式虚拟存储管理中硬件的地址转换和缺页中断,并用先进先出调度算法(FIFO)处理缺页中断。
3.算法流程图
三、直接上代码
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int page_number; //页号
int flag; //标志
int mainBlock_number; //主存块号
int change_flag; //修改标志
int disk_local; //磁盘上的位置
} page_record;
typedef struct node1
{
char opreation;
int page_number;
int page_address;
} instruct;
void pagetable(page_record* page[],int n);// 生成页表函数,共7页(4块位于主存);
void input(instruct* ot[],int counter);// 输入函数,输入指令队列;
void outData(page_record* page[],int n);// 输出页表函数,打印当前的页表信息;
int FIFO_page(page_record* pt[],instruct* ot[],int n,int counter);//FIFO调度;
int main()
{
int n=7/*页数*/,counter/*指令数*/,break_off;
page_record* page[n];// 指令队列
pagetable(page,n);// 生成页表
printf("请输入指令条数:");
scanf("%d", &counter);
instruct* operation[counter];
input(operation,counter);
printf("\n指令访存情况如下:\n");
break_off = FIFO_page(page,operation,n,counter);
printf("所有指令执行完毕,当前页表数据:\n");
outData(page,n);
printf("调用总页数:%d,缺页中断数:%d\n", counter, break_off);
printf("缺页中断率为:");
printf("%.3f\n", (float)break_off/(float)counter);
return 0;
}
void pagetable(page_record* page[],int n) // 页表
{
int i;
for (i = 0; i < n; i++)
{
page[i] = (page_record*)malloc(sizeof(page_record));// 申请一个结构体空间
page[i]->page_number = i;
if (i < 4)
page[i]->flag = 1;
else
{
page[i]->flag = 0;
page[i]->mainBlock_number = 0;
}
page[i]->change_flag = 0;
}
page[0]->mainBlock_number = 5;
page[1]->mainBlock_number = 8;
page[2]->mainBlock_number = 9;
page[3]->mainBlock_number = 1;
page[0]->disk_local = 11;
page[1]->disk_local = 12;
page[2]->disk_local = 13;
page[3]->disk_local = 21;
page[4]->disk_local = 22;
page[5]->disk_local = 23;
page[6]->disk_local = 121;
outData(page,n);
}
void outData(page_record* page[],int n)
{
int i;
printf("********************页表信息******************\n");
printf(" 页号 标志 主存块号 修改标志 磁盘位置\n");
for (i = 0; i < 7; i++)
printf(" %2d%8d%8d%12d%12d\n", page[i]->page_number, page[i]->flag, page[i]->mainBlock_number, page[i]->change_flag, page[i]->disk_local);
}
void input(instruct* ot[],int counter)
{
int i ;
printf("在一下每行输入指令信息(操作、页号和页内地址);\n");
for (i = 0; i < counter; i++)
{
printf("请输入%d/%d号指令信息:",i+1,counter);
ot[i] = (instruct*)malloc(sizeof(instruct));
scanf("%s%d%d", &ot[i]->opreation, &ot[i]->page_number, &ot[i]->page_address);
}
}
int FIFO_page(page_record* pt[],instruct* ot[],int n,int counter)
{
int i, j;
int k = 0,k1,break_off = 0,location;
for (i = 0; i < counter; i++)
{
int suspend = 1;
for (j = 0; j < n; j++){
if (ot[i]->page_number == pt[j]->page_number){
if (pt[j]->mainBlock_number != 0){
k1 = j;
break;
}
else{
printf("第%d页不在主存中,",ot[i]->page_number);
printf("将第%d页调入内存第%d页所在位置",ot[i]->page_number,pt[k]->page_number);
if(pt[k]->change_flag == 1)
printf(",第%d页被修改过,将其调出内存,并回存至磁盘中",pt[k]->page_number);
printf(".\n");
pt[j]->page_number = pt[k]->page_number;
pt[k]->page_number = ot[i]->page_number;
k1 = k;
pt[k]->flag = 1;
k = (k + 1) % 4;
break_off++;
suspend = 0;
//outData(pt,n);
printf("页面置换后,");
break;
}
}
}//for(j)
ot[i]->opreation =='S'?(pt[k1]->change_flag = 1):(pt[k1]->change_flag = 0);
//输出绝对地址
location = ot[i]->page_address + pt[k1]->mainBlock_number * 1024;
printf("第%d页在主存中,它的绝对地址为:%d\n", ot[i]->page_number, location);
if(!suspend)
printf("\n");
}//for(i)
return break_off;
}
四.测试结果
1.输入数据
2.输出数据