西安石油大学操作系统原理实验虚拟页式管理
- 格式:doc
- 大小:359.00 KB
- 文档页数:14
实验报告课程名称计算机操作系统实验名称虚拟页式管理班级计1201班学号201107010122姓名张文江指导教师赵安科实验日期2015.5.28成绩实验二 虚拟页式管理模拟请求页式存储管理中硬件的地址转换和缺页中断,并用先进先出调度算法(FIFO )处理缺页中断1.内容:模拟请求页式存储管理中硬件的地址转换和缺页中断处理2.思想:装入新页置换旧页时,若旧页在执行中没有被修改过,则不必将该页重写磁盘。
因此,页表中增加是否修改过的标志,执行“存”指令和“写”指令时将对应的修改标志置成“1”表示修改过,否则为“0”表示未修改过。
页表格式如下:页号 标志 页架号 修改标志在磁盘上位置3.要求及方法:① 设计一个地址转换程序来模拟硬件的地址转换和缺页中断。
当访问的页在主存时则形成绝对地址,但不去模拟指令的执行,可以输出转换后的绝对地址来表示一条指令已执行完成。
当访问的页不在主存中时,则输出“*页号”来表示硬件产生了一次缺页中断。
模拟地址转换流程见图1。
② 编制一个FIFO 页面调度程序;FIFO 页面调度算法总是先调出作业中最先进入主存中的哪一页。
因此可以用一个数组来表示(或构成)页号队列。
数组中每个元素是该作业已在主存中的页面号,假定分配给作业的页架数为m ,且该作业开始的m 页已装入主存,则数组可由m 个元素构成。
P[0],P[1],P[2],…,P[m-1]它们的初值为P[0]:=0,P[1]:=1,P[2]:=2,…,P[m-1]:=m-1用一指针K 指示当要调入新页时应调出的页在数组中的位置,K 的初值为“0”,当产生缺页中断后,操作系统总是选择P[K]所指出的页面调出,然后执行:P[K]:=要装入的新页页号 K :=(k+1)mod m在实验中不必实际地启动磁盘执行调出一页和装入一页的工作,而用输出“OUT 调出的页号”和“IN 要装入的新页页号”来模拟一次调出和装入过程,模拟程序的流程图见附图1。
按流程控制过程如下:提示:输入指令的页号和页内偏移和是否存指令⎩⎨⎧ 0 1非存指令存指令,若d 为-1则结束,否则进入流程控制过程,得P 1和d ,查表在主存时,绝对地址=P 1×1024+d③假定主存中页架大小为1024个字节,现有一个共7页的作业,其副本已在磁盘上。
系统为该作业分配了4个页架,且该作业的第0页至第3页已装入内存,其余3页未装入主存,该作业的页表如下:页号标志页架号修改标志在磁盘上位置0 1 5 0 0111 1 8 0 0122 1 9 0 0133 1 1 0 0214 0 0 0225 0 0 0236 0 0 121如果该作业依次执行的指令序列如下表所示:操作页号页内地址操作页号页内地址+ 0 070 移位 4 053+ 1 050 + 5 023× 2 015 存 1 037存 3 021 取 2 078取0 056 + 4 001- 6 040 存 6 084依次执行上述指令调试你所设计的程序(仅模拟指令的执行,不考虑序列中具体操作的执行)。
④为进一步考察程序的执行,可自行确定若干组指令,运行程序,核对执行结果。
图1 模拟算法流程4.实验代码:#include <windows.h>#include <conio.h>#include <stdlib.h>#include <fstream.h>#include <string.h>#include <stdio.h>/*void initialize();void createps();void displayinfo();void fifo();int findpage();void lru();*/int invalidcount = 0; // 缺页次数int vpoint; //页面访问指针int pageframe[10]; // 分配的页框int pagehistory[10]; //用以记录页框中数据访问历史int rpoint; //页面替换指针int inpflag; //缺页标志,0为不缺页,1为缺页//页面信息结构struct PageInfo{int serial[100]; // 模拟的最大访问页面数,实际控制在20以上int flag; // 标志位,0表示无页面访问数据int diseffect; // 缺页次数int total_pf; // 分配的页框数int total_pn; // 访问页面序列长度} pf_info;//初始化相关数据结构void initialize(){int i,pf;inpflag=0; //缺页标志,默认值为0不缺页pf_info.diseffect =0; //缺页次数,默认0pf_info.flag =0; //标志位,0表示无页面访问数据printf("请输入要分配的页框数:");scanf("%d",&pf);printf("\n");pf_info.total_pf =pf; //自定义输入页框数for(i=0;i<100;i++) // 清空页面序列{pf_info.serial[i]=-1;}}// 随机生成访问序列void createps(void ){int s,i,pn;initialize(); //初始化相关数据结构printf("请输入要随机产生的访问序列的长度:");scanf("%d",&pn);printf("\n");srand(rand()); //初始化随机数队列的"种子"s=((float) rand() / 32767) * 50 + pn; // 根据需求产生访问序列长度pf_info.total_pn = s;for(i=0;i<s;i++) //产生随机访问序列{pf_info.serial[i]=((float) rand() / 32767) * 16;//限定随机数大小在16以内}}// 显示当前状态及缺页情况void displayinfo(void){int i,n;if(vpoint==0){printf("\n=============页面访问序列=============\n");for(i=0; i<pf_info.total_pn; i++){printf("%d ",pf_info.serial[i]);if ((i+1) % 10 ==0) printf("\n");//每行显示10个}printf("\n======================================\n");}printf("访问= %d: 内存 ",pf_info.serial[vpoint]);for(n=0;n<pf_info.total_pf;n++) // 页框信息{if (pageframe[n] >=0)printf("%d ",pageframe[n]);// else// printf(" ");}printf("|");if(inpflag==1){printf("缺页\t");printf("缺页率:%3.1f",(float)(pf_info.diseffect)*100.00/vpoint);}printf("\n");}// 查找页面是否在内存,1为在内存,0为不在即缺页int findpage(int page){int n;for(n=0;n<pf_info.total_pf;n++){pagehistory[n]++;//页面访问历史记录}for(n=0;n<pf_info.total_pf;n++){if(pageframe[n]==page){inpflag=0;pagehistory[0]=0;return 1;}}inpflag=1; //页面不存在,缺页return 0;}// FIFO页面置换算法void fifo(void){int n,count,pstate;rpoint=0; // 页面替换指针invalidcount = 0; // 缺页数初始化为0 // 随机生成访问序count=0; // 是否装满页框// createps(); // 随机产生访问序列for(n=0;n<pf_info.total_pf;n++) // 清除页框信息pageframe[n]=-1;inpflag=0;for(vpoint=0;vpoint<pf_info.total_pn;vpoint++) // 执行算法{pstate=findpage(pf_info.serial[vpoint]);if(count<pf_info.total_pf) // 开始时不计算缺页{if(pstate==0)// 页不存在则装入页面{pageframe[rpoint]=pf_info.serial[vpoint];rpoint=(rpoint+1) % pf_info.total_pf;count++;}}else // 正常缺页置换{if(pstate==0)// 页不存在则置换页面{pageframe[rpoint]=pf_info.serial[vpoint];rpoint=(rpoint+1) % pf_info.total_pf;pf_info.diseffect=pf_info.diseffect+1; // 缺页次数加1 }}Sleep(1000);displayinfo(); // 显示当前状态} // 置换算法循环结束_getch();return;}//LRU页面置换算法/*void lru(void){int n,count,pstate,max;rpoint =0;invalidcount=0;count =0;createps();for(n=0;n<pf_info.total_pf;n++){pageframe[n]=1;pagehistory[n]=0;}inpflag = 0;for(vpoint=0;vpoint<pf_info.total_pn;vpoint++){pstate=findpage(pf_info.serial[vpoint]);if(count<pf_info.total_pf){if(pstate==0){pageframe[rpoint]=pf_info.serial[vpoint];rpoint=(rpoint+1)%pf_info.total_pf;count++;}}else{if(pstate==0){max=0;for(n=1;n<pf_info.total_pf;n++){if(pagehistory[n]>pagehistory[max]){max = n;}}rpoint=max;pageframe[rpoint]=pf_info.serial[vpoint];pagehistory[rpoint]=0;pf_info.diseffect++;}}Sleep(1000);displayinfo();}_getch();return;}*///主函数int main(int argc, char* argv[]){char ch;system("cls") ;while ( true ){printf("***********************************\n");printf(" 1: FIFO页面置算法 \n") ;/* printf(" 2: LRU页面置算法 \n") ; */printf(" 2: 生成访问序列 \n") ;printf(" 3: 退出 \n") ;printf("***********************************\n");printf( "页测试算法,必须先选2\n请输入你的选择 (1或2或3): ");do{ch = (char)_getch() ;} while(ch != '1' && ch != '2'&& ch != '3'&& ch != '4');if(ch == '3')return 0;else{cout<<endl;if(ch=='1'){system("cls") ;fifo();}/* if(ch=='2'){system("cls") ;lru();} */if(ch=='2'){createps();int i,n;if(vpoint==0){printf("\n=============页面访问序列=============\n");for(i=0; i<pf_info.total_pn; i++){printf("%d",pf_info.serial[i]);if ((i+1) % 10 ==0) printf("\n");//每行显示10个}printf("\n======================================\n");}}}}_getch() ;return 0;}5.实验结果截图:6.实验总结在实验过程中,遇到了一些问题但是在调试的过程中,会出现很多错误,有的自己可以解决,也有一些在同学的帮助下,基本都解决了所有问题。