实验四页面置换算法代码(一)
页面置换算法模拟实验报告材料

实验编号4名称页面置换算法模拟实验目的通过请求页式存储管理中页面置换算法模拟设计,以便:1、了解虚拟存储技术的特点2、掌握请求页式存储管理中页面置换算法实验内容与步骤设计一个虚拟存储区和内存工作区,并使用FIFO和LRU算法计算访问命中率。
<程序设计>先用srand()函数和rand()函数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算相应的命中率。
<程序1>#include <windows.h> //Windows版,随机函数需要,GetCurrentProcessId()需要//#include <stdlib.h>//Linux版,随机函数srand和rand需要#include <stdio.h> //printf()需要#define TRUE 1#define FALSE 0#define INV ALID -1#define NULL 0#define total_instruction 320 //共320条指令#define total_vp 32 //虚存页共32页#define clear_period 50 //访问次数清零周期typedef struct{//定义页表结构类型〔页面映射表PMT〕int pn, pfn, counter, time;//页号、页框号(块号)、一个周期内访问该页面的次数、访问时间}PMT;PMT pmt[32];typedef struct pfc_struct{//页面控制结构int pn, pfn;struct pfc_struct *next;}pfc_type;pfc_type pfc[32];pfc_type *freepf_head,*busypf_head,*busypf_tail;//空闲页头指针,忙页头指针,忙页尾指针int NoPageCount; //缺页次数int a[total_instruction];//指令流数组int page[total_instruction], offset[total_instruction];//每条指令的页和页内偏移void initialize( int );void FIFO( int );//先进先出void LRU( int );//最近最久未使用void NRU( int );//最近最不经常使用/****************************************************************************main()*****************************************************************************/ void main(){int i,s;//srand(10*getpid());//用进程号作为初始化随机数队列的种子//Linux版srand(10*GetCurrentProcessId());//用进程号作为初始化随机数的种子//Windows版s=rand()%320;//在[0,319]的指令地址之间随机选取一起点mfor(i=0;i<total_instruction;i+=4){//产生指令队列if(s<0||s>319){printf("when i==%d,error,s==%d\n",i,s);exit(0);}a[i]=s;//任意选一指令访问点m。
实验报告四

实验四存储管理常用页面置换算法模拟实验一、实验目的通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。
二、实验内容设计一个虚拟存储区和内存工作区,并使用下述算法计算访问命中率。
1、最佳淘汰算法(OPT)2、先进先出的算法(FIFO)3、最近最久未使用算法(LRU)4、最不经常使用算法(LFU)5、最近未使用算法(NUR)命中率=1-页面失效次数/页地址流长度三、实验过程1.进入LINUX系统。
打开虚拟机,在vi中编写程序,在终端输入文件名(gccxx.c),输入执行指令,屏幕上无反应,按下^C后,显示最终结果。
2、页面置换算法当CPU接收到缺页中断信号,中断处理程序先保存现场,分析中断原因,转入缺页中断处理程序。
该程序通过查找页表,得到该页所在外存的物理块号。
如果此时内存未满,能容纳新页,则启动磁盘I/O将所缺之页调入内存,然后修改页表。
如果内存已满,则须按某种置换算法从内存中选出一页准备换出,是否重新写盘由页表的修改位决定,然后将缺页调入,修改页表。
利用修改后的页表,去形成所要访问数据的物理地址,再去访问内存数据。
整个页面的调入过程对用户是透明的。
常用的页面置换算法有1、最佳置换算法(Optimal)2、先进先出法(FisrtInFirstOut)3、最近最久未使用(LeastRecentlyUsed)4、最不经常使用法(LeastFrequentlyUsed)5、最近未使用法(NoUsedRecently)3.运行结果:四、回答问题1、为什么OPT在执行时会有错误产生?当需要淘汰一个内存页面时,这种算法力图选择该进程内存各个页面中永远不再需要的页,若找不到,则选择最久以后才会用到的页。
这种算法有最小的缺页率。
问题是它需要知道运行进程今后的整个访问踪迹,这往往难以做到,因而它只有理论上的意义。
页面置换算法模拟实验报告

if(block[i].timer >= block[pos].timer)
pos = i;//找到应予置换页面,返回BLOCK中位置
return pos;
}
void PRA::display(void)
{
for(int i=0; i<Bsize; i++)
}
}
int PRA::findSpace(void)
{
for(int i=0; i<Bsize; i++)
if(block[i].content == -1)
return i;//找到空闲内存,返回BLOCK中位置
return -1;
}
int PRA::findExist(int curpage)
{
if(exist != -1)
{
cout<<"不缺页"<<endl;
}
else
{
space = findSpace();
if(space != -1)
{
block[space] = page[i];
display();
}
else
{
for(int k=0; k<Bsize; k++)
for(int j=i; j<Psize; j++)
int findReplace(void); //查找应予置换的页面
void display(void); //显示
void FIFO(void);//FIFO算法
操作系统页面置换算法代码

通达学院课程设计I报告(2018/2019学年第2学期)题目:页面置换算法专业计算机科学与技术学生姓名班级学号指导教师指导单位计算机学院日期2019.5.13-5.23指导教师成绩评定表页面置换算法一、课题容和要求通过实现页面置换的四种算法,理解虚拟存储器的概念、实现方法,页面分配的总体原则、进程运行时系统是怎样选择换出页面的,并分析四种不同的算法各自的优缺点是哪些。
以下算法都要实现:1) 最佳置换算法(OPT):将以后永不使用的或许是在最长(未来)时间不再被访问的页面换出。
2) 先进先出算法(FIFO):淘汰最先进入存的页面,即选择在存中驻留时间最久的页面予以淘汰。
3) 最近最久未使用算法(LRU):淘汰最近最久未被使用的页面。
4) 最不经常使用算法(LFU)设计要求:1、编写算法,实现页面置换算法;2、针对存地址引用串,运行页面置换算法进行页面置换;3、算法所需的各种参数由输入产生(手工输入或者随机数产生);4、输出存驻留的页面集合,缺页次数以及缺页率;二、需求分析通过这次实验,加深对虚拟存页面置换概念的理解,进一步掌握先进先出FIFO、最佳置换OPI和最近最久未使用LRU页面置换算法及最不经常使用算法LFU的实现方法。
通过已知最小物理块数、页面个数、页面访问序列、及采用置换方式可以得出页面置换的缺页次数和缺页率,及每次缺页时物理块中存储!(1) 输入的形式页面序列物理块数、页面数、页面序列(2) 输出的形式驻留页面集合、缺页数、缺页率注:如果命中用 * 表示,为空用 -1 表示(3)程序所能达到的功能模拟先进先出FIFO、最佳置换OPI、最近最久未使用LRU页面置换算法和最不经常使用算法LFU的工作过程。
假设存中分配给每个进程的最小物理块数为m,在进程运行过程中要访问的页面个数为n,页面访问序列为P1, …,Pn,分别利用不同的页面置换算法调度进程的页面访问序列,给出页面访问序列的置换过程,计算每种算法缺页次数和缺页率。
存储管理实验报告代码(3篇)

第1篇一、实验目的通过本次实验,掌握操作系统存储管理的基本原理,了解不同存储管理策略的实现方法,并能够通过代码模拟实现其中的一种策略,以加深对存储管理机制的理解。
二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.83. 开发工具:PyCharm三、实验内容本次实验主要模拟实现页式存储管理中的FIFO(先进先出)页面置换算法。
四、实验步骤1. 定义一个类Page,用于表示页面,包含页号、标志位和物理块号等信息。
```pythonclass Page:def __init__(self, page_number):self.page_number = page_numberself.flag = 0 0表示不在内存,1表示在内存self.frame_number = -1 物理块号,-1表示未分配```2. 定义一个类Memory,用于模拟内存,包含物理页列表、页面置换算法和页面替换操作。
```pythonclass Memory:def __init__(self, frames):self.frames = framesself.page_table = []def allocate_page(self, page_number):for page in self.page_table:if page.page_number == page_number:return pagefor page in self.page_table:if page.flag == 0:page.flag = 1page.frame_number = self.frames.pop(0) return pageFIFO页面置换算法for page in reversed(self.page_table):if page.flag == 0:self.frames.append(page.frame_number) page.flag = 1page.frame_number = self.frames.pop(0) return page页面置换失败raise Exception("Memory full")def deallocate_page(self, page_number):for page in self.page_table:if page.page_number == page_number:page.flag = 0page.frame_number = -1self.frames.append(page.frame_number)return```3. 定义一个类PageReplacementSimulator,用于模拟页面置换过程。
页面置换算法源程序+实验报告

课程名称:操作系统F实验项目:操作系统实验实验地点:博学楼学院502机房专业班级:物联网1102学生姓名:陶志骞学号:2011001585 指导教师:郭昊2013年11 月20 日一.目的和要求(一)目的存储管理的主要功能之一是合理地分配空间。
请求页式管理是一种常用的虚拟存储管理技术。
本实验的目的是通过请求页式管理中页面置换算法的模拟设计,来了解虚拟存储技术的特点,掌握请求页式管理的页面置换算法。
(二)要求模拟页式虚拟存储管理中硬件的地址转换和缺页中断,并用先进先出调度算法(FIFO)处理缺页中断。
二.实验内容(1)为了装入一个页面而必须调出一页时,如果被选中调出的页面在执行中没有修改过,则不必把该页写到磁盘上。
因此,在页表中可以增加是否修改过的标志,当执行“存”指令“写”指令是把对应页的修改标志置“1”表示该页修改过,为“0”表示该页没有修改过。
(2)设计一个地址转换程序来模拟硬件的地址转换和缺页中断。
当访问的页在主存时则形成绝对地址,但不去模拟指令的执行,可用输出转换后的绝对地址来表示一条指令已完成。
当访问的页不在主存时则输出“*该页页号”来表示硬件产生了一次缺页中断。
调用模拟地址转换程序。
(3)编制一个FIFO页面调试程序。
FIFO页面调试算法总是先调出作业中最先进入主存的那一页,因此,可以用一个数组来构成页号队列。
数组中每个元素是该作业已在主存的页面好,假定分配给作业的主存块数为m,且该作业开始的m页已装入主存,则数组可有m个元素组成:P[0],P[1],…,P[m-1] 她们的初值为:P[0]:=0,P[1]:=1,…,P[m-1]:=m-1用一指针k指示当要装入新页时应调出的页在数组的位置,k的初值为0。
当产生缺页中断后,操作系统总是选择P[k]所指出的页面调出,然后执行:P[k]:=要装入的新页页号K:=(k+1)mod m(4)假定主存的每块长度为1024个字节,现有一个共7页的作业,其副本也已在磁盘上.系统为该作业分配了4块主存块,且该作业的第0页至第3页已经装入主存,其余3页尚未装入主存,该作业的页表如下:假设该作业依次执行的指令如下:三.实验流程图四.实验程序#include <iostream>#include <iostream.h>#include <iomanip.h>#include <ctype.h>#define N 6//实验中假定的页表长度#define M 4 //主存物理块数struct{int lnumber; //页号int flag; //表示该页是否在主存,"1"表示在主存,"0"表示不在主存 int pnumber; //该页所在主存块的块号int write; //该页是否被修改过,"1"表示修改过,"0"表示没有修改过 int dnumber; //该页存放在磁盘上的位置,即磁盘块号}page[N]; //页表定义int p[M]; //用数组模拟]FIFO算法中的队列(使用循环队列)int head;void initial(void);int do_mmap(int); //模拟地址转换void do_page_fault(int); //缺页中断处理程序void run_first_instructon(int); //执行进程的第一条指令void run_a_instruction(int); //CPU执行一条指令void print_page_and_fifoqueue(void); //输出页表和FIFO队列main(){int laddress, paddress; //逻辑地址,物理地址int lnumber, ad, pnumber; //页号,页内地址和物理块号initial();print_page_and_fifoqueue(); //输出页表和FIFO队列run_first_instructon(0x0000); //运行进程的第一条指令的地址cout<<"输入下一条指令的逻辑地址(0~32767)(-1 to end)"<<endl;cin>>laddress;while(laddress>32767){cout<<"输入错误! 请重新输入下一条指令的逻辑地址(0~32767)(-1 to end)"<<endl;cin>>laddress;}while(laddress!=-1){lnumber=laddress>>10; //取逻辑地址的页号lnumberif(page[lnumber].flag==1){ //指令所在的页面已装入在内存中paddress=do_mmap(laddress); //形成物理地址cout<<paddress<<"输出转换后的物理地址"<<endl;run_a_instruction(paddress);cout<<"此指令执行是否修改所在页lnumber="<<lnumber<<"(y/n?) ";char change;cin>>change;if(tolower(change)=='y'){page[lnumber].write=1;print_page_and_fifoqueue();}}else{ //缺页中断cout<<lnumber<<"输出该页的页号--表示硬件产生缺页中断"<<endl;do_page_fault(lnumber); //直接转去缺页中断处理continue; //本循环结束,重新执行指令}cout<<"输入下一条指令的逻辑地址((0~32767),-1 to end)\n";cin>>laddress;while(laddress>32767){ //输入正确性检测cout<<"输入错误! 请重新输入下一条指令的逻辑地址(0~32767)(-1 to end)"<<endl;cin>>laddress;}}cout<<"进程运行结束!"<<endl;system("PAUSE");return 0;}//手工初始化页表和p[M]队列void initial(void){int i;for(i=0; i<=5; i++){page[i].lnumber=i;if(i<=M-1){ //预装入算法初始化页表的前四项cout<<"输入页号为 "<<i<<" 所在内存的物理块号(预装入前四个页面):";cin>>page[i].pnumber;page[i].flag=1; //存在标志置1}}//初始化FIFO的队列head=0;for(i=0; i<=M-1; i++)p[i]=i;}//输出页表和FIFO队列void print_page_and_fifoqueue(void){int i;cout<<"输出页表!\n";cout<<setw(10)<<"lnumber"<<setw(9)<<"flag"<<setw(10)<<"pnumber"<<setw(10)<<"write"<<setw(10)<<"dnumber"<<endl;for(i=0; i<=N-1; i++)cout<<setw(7)<<page[i].lnumber<<setw(10)<<page[i].flag<<setw(10)< <page[i].pnumber<<setw(10)<<page[i].write<<setw(10)<<page[i].dnumber<<endl;cout<<"输出FIFO对列:\n";cout<<setw(10)<<"NO"<<setw(40)<<"page(已在主存的页号lnumber)\n";cout<<"head="<<head<<endl;for(i=0; i<=M-1;i++)cout<<setw(10)<<i<<setw(15)<<p[i]<<endl;}//模拟地址转换int do_mmap(int laddress){int lnumber, ad, pnumber, paddress;lnumber=laddress>>10; //取逻辑地址的页号lnumberad=laddress&0x3ff; //页内地址pnumber=page[lnumber].pnumber; //从页表中取得块号pnumberpaddress=pnumber<<10|ad;return paddress;}//CPU执行一条指令,输出物理地址表示指令执行完成void run_a_instruction(int paddress){cout<<paddress<<" 输出物理地址--表示指令执行完成"<<endl;}//执行进程的第一条指令void run_first_instructon(int laddress){int lnumber, ad, pnumber, paddress;lnumber=laddress>>10; //取逻辑地址的页号if(page[lnumber].flag==1)paddress=do_mmap(laddress); //形成物理地址cout<<paddress<<"输出转换后的物理地址"<<endl;run_a_instruction(paddress);cout<<"此指令执行(0x0000)是否修改所在页面lnumber="<<lnumber<<"(y/n?) ";char change;cin>>change;if(tolower(change)=='y'){ //若指令执行完时修改了页面,则置write 标志位位1page[lnumber].write=1;print_page_and_fifoqueue();}cout<<"********第一条指令执行完成(地址为0x0000)***********"<<endl;}//页面写回磁盘void write_to_harddisk(int j){cout<<j<<"输出已修改的淘汰的页号--表示该页写回了磁盘"<<endl;}//缺页中断处理程序void do_page_fault(int lnumber){int j; //j是选择淘汰的页j=p[head];p[head]=lnumber; //lnumber是新装入的页号head=(head+1)%M;//若淘汰出主存的页j已修改,则写会磁盘if(page[j].write==1)write_to_harddisk(j); //页j写回磁盘//修改页表page[j].flag=0; //页表中第j页的存在标志为0page[lnumber].flag=1; //页表第lnumber的存在标志为1page[lnumber].write=0; //页表第lnumber的修改标志为0page[lnumber].pnumber=page[j].pnumber; //第拉怒目布尔页的主存块号为第j页原主存块号cout<<lnumber<<"输出该页--表示该页调入了主存"<<endl;cout<<"按任意键将查看“页面置换”之后的页表page[N]和FIFO队列信息"<<endl;system("PAUSE");print_page_and_fifoqueue();}五.实验结果。
实验报告页面置换算法(c语言实现)

实验三页面置换算法#include<iostream.h>#include <stdlib.h>#include <time.h>#include <stdio.h>#define L 20int M; struct Proi nt num,time;};I nput(int m,Pro p[L]){i nt i,j,c;c out<<"请输入实际页面走向长度L(15<=L<=20):";d o{c in>>m;i f(m>20||m<15)cout<<"实际页面长度须在15~20之间;请重新输入L:";e lse break;}while(1);j=time(NULL);s rand(j);c out<<"输出随机数: ";f or(i=0;i<m;i++){p[i].num=rand( )%10+1;p[i].time=0;c out<<p[i].num<<" ";}c out<<endl;r eturn m;}v oid print(Pro *page1){P ro *page=new Pro[M];p age=page1;f or(int i=0;i<M;i++)i f(page[i].num==-1)c out<<" ";e lsec out<<page[i].num<<" ";c out<<"√"<<endl;}i nt Search(int e,Pro *page1 ){P ro *page=new Pro[M];p age=page1;f or(int i=0;i<M;i++) if(e==page[i].num) return i; r eturn -1;}i nt Max(Pro *page1){}i nt Count(Pro *page1,int i,int t,Pro p[L]){}i nt main(){i nt c;i nt m=0,t=0;f loat n=0;P ro p[L];c out<<"********************************************* "<<endl;c out<<" * 页式存储管理*"<<endl;c out<<"********************************************* "<<endl;c out<<"请输入可用内存页面数m(3~5): ";d o{c in>>M;i f(M>5||M<3)c out<<"内存块M须在3~5之间,请重新输入M:";e lse break;}while(1);m=Input(m,p);P ro *page=new Pro[M];c out<<"^-^欢迎进入操作系统界面^-^"<<endl;c out<<"1:FIFO页面置换"<<endl;c out<<"2:LRU页面置换"<<endl;c out<<"3:OPT页面置换"<<endl;c out<<"4:退出"<<endl;d o{c out<<"按1~4键操作:"<<endl;c in>>c;s ystem("cls");f or(int i=0;i<M;i++){p age[i].num=-1;p age[i].time=m-1-i;}i=0;i f(c==1){n=0;c out<<"******************************************"<<endl;c out<<endl;c out<<" FIFO算法页面置换情况如下: "<<endl;cout<<endl;c out<<"******************************************"<<endl;w hile(i<m){i f(Search(p[i].num,page)>=0) {cout<<p[i].num<<" "; p[i].numc out<<"不缺页"<<endl;i++;}e lse {i f(t==M)t=0;e lse{n++;p age[t].num=p[i].num;c out<<p[i].num<<" ";p rint(page);t++;i++;}}}c out<<"缺页次数:"<<n<<" }i f(c==2){n=0;c out<<"******************************************"<<endl;c out<<endl;c out<<" LRU算法页面置换情况如下: "<<endl;c out<<endl;c out<<"******************************************"<<endl;w hile(i<m){i nt a;t=Search(p[i].num,page);i f(t>=0){p age[t].time=0;for(a=0;a<M;a++)i f(a!=t)page[a].time++;cout<<p[i].num<<" ";c out<<"不缺页"<<endl;}e lse{n++; t=Max(page);page[t].num=p[i].num; page[t].time=0;cout<<p[i].num<<" ";p rint(page);f or(a=0;a<M;a++)i f(a!=t)page[a].time++;}i++;}c out<<"缺页次数:"<<n<<" 缺页率:"<<n/m<<endl;}i f(c==3){n=0;c out<<"******************************************"<<endl;c out<<endl;c out<<" OPT算法置换情况如下:"<<endl;c out<<endl;c out<<"******************************************"<<endl;w hile(i<m){i f(Search(p[i].num,page)>=0){c out<<p[i].num<<" ";c out<<"不缺页"<<endl;i++;}e lse{i nt a=0;f or(t=0;t<M;t++)i f(page[t].num==0)a++;if(a!=0) {i nt q=M;f or(t=0;t<M;t++)i f(page[t].num==0&&q>t)q=t;p age[q].num=p[i].num;n++;c out<<p[i].num<<" ";p rint(page);i++;}e lse{i nt temp=0,s;f or(t=0;t<M;t++)i f(temp<Count(page,i,t,p)){t emp=Count(page,i,t,p);s=t;}page[s].num=p[i].num;n++;c out<<p[i].num<<" ";p rint(page);i++;}}}c out<<"缺页次数:"<<n<<" 缺页率:"<<n/m<<endl;}i f(c==4){c out<<" ^-^再见!^-^ "<<endl;}}while(c==1||c==2||c==3||c==4);r eturn 0;}结果:完成相关实验并且获得预期结果.。
页面置换算法实验报告

页面置换算法实验报告一、实验目的本次实验的目的是通过模拟页面置换算法的过程,了解不同算法的优缺点,掌握算法的实现方法,以及对算法的性能进行评估。
二、实验原理页面置换算法是操作系统中的一个重要概念,它是为了解决内存不足的问题而产生的。
当系统中的进程需要使用内存时,如果内存已经被占满,就需要将一些页面从内存中置换出去,以便为新的页面腾出空间。
页面置换算法就是用来决定哪些页面应该被置换出去的算法。
常见的页面置换算法有以下几种:1. 最佳置换算法(OPT)最佳置换算法是一种理论上的最优算法,它总是选择最长时间内不会被访问的页面进行置换。
但是,由于无法预测未来的页面访问情况,因此最佳置换算法无法在实际中使用。
2. 先进先出置换算法(FIFO)先进先出置换算法是一种简单的置换算法,它总是选择最先进入内存的页面进行置换。
但是,这种算法容易出现“抖动”现象,即频繁地将页面置换出去,然后再将其置换回来。
3. 最近最久未使用置换算法(LRU)最近最久未使用置换算法是一种比较常用的置换算法,它总是选择最长时间未被访问的页面进行置换。
这种算法可以避免“抖动”现象,但是实现起来比较复杂。
4. 时钟置换算法(Clock)时钟置换算法是一种改进的FIFO算法,它通过维护一个环形链表来实现页面置换。
当需要置换页面时,算法会从当前位置开始扫描链表,如果找到一个未被访问的页面,则将其置换出去。
如果扫描一圈后都没有找到未被访问的页面,则将当前位置的页面置换出去。
三、实验过程本次实验使用Python语言编写了一个页面置换算法模拟程序,可以模拟上述四种算法的过程,并输出算法的性能指标。
程序的主要流程如下:1. 读取输入文件,获取页面访问序列和内存大小等参数。
2. 根据选择的算法,初始化相应的数据结构。
3. 遍历页面访问序列,模拟页面置换的过程。
4. 输出算法的性能指标,包括缺页率、页面置换次数等。
下面分别介绍四种算法的实现方法。
1. 最佳置换算法(OPT)最佳置换算法需要预测未来的页面访问情况,因此需要遍历整个页面访问序列,找到最长时间内不会被访问的页面。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验四页面置换算法模拟(2)一.题目要求:设计一个虚拟存储区和内存工作区,编程序演示下述算法的具体实现过程,并计算访问命中率:要求设计主界面以灵活选择某算法,且以下算法都要实现1) 最佳置换算法(OPT) :将以后永不使用的或许是在最长(未来)时间内不再被访问的页面换出。
2) 先进先出算法(FIFO) :淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。
3) 最近最久未使用算法(LRU) :淘汰最近最久未被使用的页面。
4) 最不经常使用算法(LFU)二.实验目的:1、用C 语言编写OPT、FIFO、LRU,LFU 四种置换算法。
2、熟悉内存分页管理策略。
3、了解页面置换的算法。
4、掌握一般常用的调度算法。
5、根据方案使算法得以模拟实现。
6、锻炼知识的运用能力和实践能力。
三.相关知识:1.虚拟存储器的引入:局部性原理:程序在执行时在一较短时间内仅限于某个部分;相应的,它所访问的存储空间也局限于某个区域,它主要表现在以下两个方面:时间局限性和空间局限性。
2.虚拟存储器的定义:虚拟存储器是只具有请求调入功能和置换功能,能从逻辑上对内存容量进行扩充的一种存储器系统。
3.虚拟存储器的实现方式:分页请求系统,它是在分页系统的基础上,增加了请求调页功能、页面置换功能所形成的页面形式虚拟存储系统。
请求分段系统,它是在分段系统的基础上,增加了请求调段及分段置换功能后,所形成的段式虚拟存储系统。
4.页面分配:平均分配算法,是将系统中所有可供分配的物理块,平均分配给各个进程。
按比例分配算法,根据进程的大小按比例分配物理块。
考虑优先的分配算法,把内存中可供分配的所有物理块分成两部分:一部分按比例地分配给各进程;另一部分则根据个进程的优先权,适当的增加其相应份额后,分配给各进程。
5.页面置换算法:常用的页面置换算法有OPT、FIFO、LRU、Clock、LFU、PBA 等。
四.设计思想:选择置换算法,先输入所有页面号,为系统分配物理块,依次进行置换:OPT 基本思想:是用一维数组page[pSIZE] 存储页面号序列,memery[mSIZE] 是存储装入物理块中的页面。
数组next[mSIZE] 记录物理块中对应页面的最后访问时间。
每当发生缺页时,就从物理块中找出最后访问时间最大的页面,调出该页,换入所缺的页面。
【特别声明】若物理块中的页面都不再使用,则每次都置换物理块中第一个位置的页面。
FIFO 基本思想:是用队列存储内存中的页面,队列的特点是先进先出,与该算法是一致的,所以每当发生缺页时,就从队头删除一页,而从队尾加入缺页。
或者借助辅助数组time[mSIZE] 记录物理块中对应页面的进入时间,每次需要置换时换出进入时间最小的页面。
LRU 基本思想:是用一维数组page[pSIZE] 存储页面号序列,memery[mSIZE] 是存储装入物理块中的页面。
数组flag[10] 标记页面的访问时间。
每当使用页面时,刷新访问时间。
发生缺页时,就从物理块中页面标记最小的一页,调出该页,换入所缺的页面。
五.流程图:如下页所示开始载入页号序列,从第0 个得到页号将页号放入物理块中,编号加 1否引用串编号大于物理块数?是是页号在物理块中?是根据选择的置换算法完成置换是页号序列载完?是结束六.源代码:如下页所示【使用 C 语言】#include <stdio.h>#include <conio.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]);elseprintf("%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();- 5 -}/*载入数据*/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(" ┣━━━━━━━━━━━━━━━━━━━━━━━━━┫\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]);elseprintf("%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]);elseprintf(" | |"); }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(" ");elseprintf(" |%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");elseprintf(" Θ");}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++;elseflag[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);}七.参考文献:1. 严蔚敏, 吴伟民. 数据结构. 清华大学出版社, 2005.112. 谭浩强. C 语言程序设计. 清华大学出版社, 2005.113. 于帆, 赵妮. 程序设计基础(C 语言版). 清华大学出版社, 2006.114. 汤小丹, 梁红兵, 哲凤屏, 汤子瀛. 计算机操作系统. 西安电子科技大学出版社, 2007.5- 11 -。