页面置换算法模拟实验
页面置换算法实验报告
页面置换算法实验报告
一、实验内容
本次实验主要围绕页面置换算法进行,以实验课本的实例介绍,采用FIFO页面置换算法对后面提到的参数进行置换,最终得出页面置换的结果和比较所得结果。
二、实验步骤
(一) 熟悉FIFO算法
首先是要了解FIFO页面置换算法,FIFO全称(First In First Out),按页面进入内存的顺序来替换相应内存页面,先进先出,将先进入内存的页面先替换出去。
(二) 阅读实验课本
在阅读实验课本之前要先熟悉实验书上所介绍的FIFO算法,然后在实验书上找出需要做的实验,并对实验环境和表格进行观察,掌握实验的基本内容。
(三) 开始页面置换
在开始实验之前,熟悉实验环境,根据实验书上的参数,首先模拟进程分配内存,根据FIFO算法去进行计算,根据上表中的参数去比较,最后得出最终结果。
(四) 在本次实验的补充
这次实验中,可以把FIFO的概念应用到实际应用中,也可以模拟不同情况,例如改变页面的大小,观察不同页面置换算法的结果,实验出最合适的结果。
三、实验结论
本次实验是为了了解FIFO页面置换算法,实验出最终的结果,最后得出页面置换的结果及比较结果。
页面置换算法实验(内含完整代码)
实验二存储管理一、实验目的通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。
二、实验内容基于一个虚拟存储区和内存工作区,设计下述算法并计算访问命中率。
1、最佳淘汰算法(OPT)2、先进先出的算法(FIFO)3、最近最久未使用算法(LRU)4、简单时钟(钟表)算法(CLOCK)命中率=1-页面失效次数/页地址流(序列)长度三、实验原理简述UNIX中,为了提高内存利用率,提供了内外存进程对换机制;内存空间的分配和回收均以页为单位进行;一个进程只需将其一部分(段或页)调入内存便可运行;还支持请求调页的存储管理方式。
当进程在运行中需要访问某部分程序和数据时,发现其所在页面不在内存,就立即提出请求(向CPU发出缺中断),由系统将其所需页面调入内存。
这种页面调入方式叫请求调页。
为实现请求调页,核心配置了四种数据结构:页表、页帧(框)号、访问位、修改位、有效位、保护位等。
当CPU接收到缺页中断信号,中断处理程序先保存现场,分析中断原因,转入缺页中断处理程序。
该程序通过查找页表,得到该页所在外存的物理块号。
如果此时内存未满,能容纳新页,则启动磁盘I/O将所缺之页调入内存,然后修改页表。
如果内存已满,则须按某种置换算法从内存中选出一页准备换出,是否重新写盘由页表的修改位决定,然后将缺页调入,修改页表。
利用修改后的页表,去形成所要访问数据的物理地址,再去访问内存数据。
整个页面的调入过程对用户是透明的。
四、算法描述本实验的程序设计基本上按照实验内容进行。
即使用srand( )和rand( )函数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率。
(1)通过随机数产生一个指令序列,共320条指令。
指令的地址按下述原则生成:A:50%的指令是顺序执行的B:25%的指令是均匀分布在前地址部分C:25%的指令是均匀分布在后地址部分具体的实施方法是:A:在[0,319]的指令地址之间随机选取一起点mB:顺序执行一条指令,即执行地址为m+1的指令C:在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’D:顺序执行一条指令,其地址为m’+1E:在后地址[m’+2,319]中随机选取一条指令并执行F:重复步骤A-E,直到320次指令(2)将指令序列变换为页地址流设:页面大小为1K;用户内存(页帧)容量为4页~32页;用户虚存容量为32K。
常用页面置换算法模拟实验
实验环境
Windows xp 、Microsoft Visual c++ 6.0
实验目的与要求:
通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特 点,掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并 比较它们的效率。
实验内容:
设计一个虚拟存储区和内存工作区,并使用下述算法计算访问命中率。
struct Pro { int num,time; };
二、 输入实际页数
函数名称:int Input(int m,Pro p[M]) 函数功能:输入实际页数,并输入各页面号
三、 查找页面是否存在
函数名称:int Search(int e,Pro *page1)
四、 找出离现在时间最长的页面
函数名称:int Max(Pro *p Nhomakorabeage1)
五、 比较页面
函数名称:int Compfu(Pro *page1,int i,int t,Pro p[M])
六、 打印当前的页面
函数名称:void print(Pro *page1)
七、 主函数
函数名称:int main() 1、 输入可用内存页面数 2、 初试化页面基本情况 3、 选择置换页面算法:FIFO 页面置换、LRU 页面置换、OPT 页面置换 显示页面置换情况 4、 5、 输出缺页次数和缺页率 6、 按其它键结束程序。
实验总结:
1.最佳淘汰算法(OPT) 2.先进先出的算法(FIFO) 3.最近最久未使用算法(LRU) 命中率=1-页面失效次数/页地址流长度
1、一个算法的实现,要考虑很多的全面,要想写好算法,必须将数据结构和 C 语言学习好。
操作系统实验 页面置换算法模拟
实验四页面置换算法模拟一、实验内容简要描述开发语言及实现平台或实验环境C++/JA V ATurbo C / Microsoft Visual Studio 6.0 / Microsoft Visual Studio .NET 2010实验目的(1)了解内存分页管理策略(2)掌握调页策略(3)掌握一般常用的调度算法(4)学会各种存储分配算法的实现方法。
(5)了解页面大小和内存实际容量对命中率的影响。
【实验内容】编程实现页面置换算法,最少实现两种算法,比较算法的优劣,并将调试结果显示在计算机屏幕上,并检测机算和笔算的一致性。
【实验要求】(1)采用页式分配存储方案,通过分别计算不同算法的命中率来比较算法的优劣,同时也考虑页面大小及内存实际容量对命中率的影响;(2)实现OPT 算法(最优置换算法) 、LRU 算法(Least Recently) 、FIFO 算法(First IN First Out)的模拟;(3)使用某种编程语言模拟页面置换算法。
二、报告主要内容1.设计思路A、设计页面走向、物理块数等初值。
B、编制程序,使用多种算法实现页面置换。
C、计算和比较缺页率。
最佳置换算法OPT(Optimal)它是由Belady于1966年提出的一种理论上的算法。
其所选择的被淘汰页面,将是以后永不使用的或许是在最长(未来)时间内不再被访问的页面。
采用最佳置换算法,通常可保证获得最低的缺页率。
但由于人目前还无法预知一个进程在内存的若干个页面中,哪一个页面是未来最长时间内不再被访问的,因而该算法是无法实现的,但是可以利用此算法来评价其它算法。
如果编写程序模拟该算法,可以提前设定页面访问次序,获知某个页面是否在未来不再被访问。
2.画流程图3.实验结果(输入、输出截图)程序运行结果4.主要代码#include "stdio.h"#include "stdlib.h"#include "math.h"#include "conio.h"#include "time.h"#define TRUE 1#define FALSE 0#define NULL 0#define total_instruction 20#define total_vp 10typedef struct{ int pn,pfn;}pv_type;pv_type pv[10];typedef struct pf_struct{ int pn,pfn;struct pf_struct *next;}pf_type;pf_type pf[20],*free_head,*busy_head,*busy_tail,*q; int page[total_instruction];int total_pf;int count;void initialiaze(){ int i;count=0;for(i=0;i<total_vp;i++){ pv[i].pn=i;pv[i].pfn=-1;}printf("请输入实页数目:");scanf("%d",&total_pf);for(i=0;i<=total_pf-1;i++){ pf[i].next=&pf[i+1];pf[i].pfn=i+1;pf[i].pn=-1;}pf[total_pf-1].next=NULL;free_head=&pf[0];printf("随机产生的页地址流为:\n");for(i=0;i<total_instruction;i++){ page[i]=rand()%10;printf("%2d",page[i]);}}void FIFO(){ int i,j;pf_type *p;q=busy_head=busy_tail=NULL;for(i=0;i<=total_instruction-1;i++){ printf("\n第%d次执行:",i+1);if(pv[page[i]].pfn==-1){ count+=1;printf("缺页,缺页次数count=%d,",count);if(free_head==NULL){printf("实页%d中的页面%d将被置换出去",busy_head->pfn,busy_head->pn);p=busy_head->next;pv[busy_head->pn].pfn=-1;free_head=busy_head;free_head->next=NULL;busy_head=p;}p=free_head->next;free_head->next=NULL;free_head->pn=page[i];pv[page[i]].pfn=free_head->pn;if(busy_tail==NULL)busy_head=busy_tail=free_head;else{ busy_tail->next=free_head;busy_tail=free_head;}free_head=p;}else printf("命中,缺页次数不变,仍为count=%d",count);printf("\npfn pn");for(j=0;j<=total_pf-1;j++){if(pf[j].pn!=-1)printf("\n%d%8d",pf[j].pfn,pf[j].pn);}}printf("\n先进先出算法的命中率为:%6.4f\n缺页总次数为%d\n",1-(float)count/20,count);}void main(){srand((unsigned)time(NULL));initialiaze();FIFO();三、实验心得(实验中遇到的问题及解决过程、实验中产生的错误及原因分析、实验的体会及收获、对做好今后实验提出建设性建议等。
实验四页面置换算法代码
实验四页面置换算法模拟(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]是存储装入物理块中的页面。
页面置换算法实验报告
页面置换算法实验报告页面置换算法实验报告一、引言在计算机操作系统中,页面置换算法是一种重要的内存管理策略。
当物理内存不足以容纳所有需要运行的进程时,操作系统需要根据一定的算法将部分页面从内存中换出,以便为新的页面腾出空间。
本实验旨在通过实际操作,对比不同的页面置换算法在不同场景下的性能表现。
二、实验背景在计算机系统中,每个进程都有自己的虚拟内存空间,而物理内存空间是有限的。
当进程需要访问某个页面时,如果该页面不在物理内存中,就会发生缺页中断,操作系统需要根据页面置换算法选择一个页面将其换出,然后将需要访问的页面换入。
常见的页面置换算法有先进先出(FIFO)、最近最久未使用(LRU)、时钟(Clock)等。
三、实验目的本实验旨在通过模拟不同的页面置换算法,比较它们在不同情况下的缺页率和效率。
通过实验结果,评估各个算法在不同场景下的优劣,为实际系统的内存管理提供参考。
四、实验设计与方法本实验选择了三种常见的页面置换算法进行比较:FIFO、LRU和Clock。
我们使用C++编程语言模拟了一个简单的内存管理系统,并通过产生不同的访存序列来模拟不同的场景。
实验中,我们设置了不同的物理内存大小,访存序列长度和页面大小,以模拟不同的系统环境。
五、实验结果与分析在实验中,我们分别测试了FIFO、LRU和Clock算法在不同的系统环境下的表现。
通过统计不同算法的缺页率和运行时间,得出以下结论:1. FIFO算法FIFO算法是最简单的页面置换算法,它按照页面进入内存的顺序进行置换。
实验结果表明,FIFO算法在缺页率方面表现一般,特别是在访存序列具有局部性的情况下,其性能明显下降。
这是因为FIFO算法无法区分不同页面的重要性,可能会将经常使用的页面换出,导致缺页率升高。
2. LRU算法LRU算法是一种基于页面访问时间的置换算法,它认为最近被访问的页面很可能在未来会被再次访问。
实验结果表明,LRU算法在缺页率方面表现较好,特别是在访存序列具有较强的局部性时,其性能明显优于FIFO算法。
页面置换算法实验报告
页面置换算法实验报告背景页面置换算法是计算机操作系统中的一个重要概念,它用于解决操作系统需要共享有限的物理内存资源给多个进程使用的问题。
在操作系统中,每个进程都有自己的虚拟地址空间,但实际的物理内存资源是有限的。
当物理内存不足时,操作系统需要根据一定的策略将一部分进程暂时从内存中移出,以便为其他进程让出空间,而后再从外存中将其重新加载到内存中。
这个过程就是页面置换。
页面置换算法有很多种,比如最优页面置换算法(Optimal)、先进先出页面置换算法(FIFO)、最近最久未使用页面置换算法(LRU)等等。
不同的算法对于系统性能、响应时间等指标有着不同的影响,因此在实际应用中需要选择合适的算法来平衡各种需求。
本实验旨在通过模拟页面置换算法,并对不同算法进行性能分析,以便了解各种算法的优缺点,为实际系统的选择提供依据。
分析在实验中,我们选择了三种常用的页面置换算法,分别是FIFO、LRU和Optimal。
下面对这三种算法进行详细的分析和说明。
先进先出页面置换算法(FIFO)FIFO算法是最简单和最直观的页面置换算法。
它按照页面进入内存的顺序来选择被淘汰的页面。
当内存不足时,选择最早进入内存的页面进行置换,即将其从内存中移出。
FIFO算法不需要进行进一步的页面访问计算,只需要维护一个页面进入内存的队列即可,因此实现起来比较简单。
然而,由于FIFO算法没有考虑页面的访问频率和重要性,所以可能会导致被频繁访问的页面被淘汰出内存,从而影响系统的性能。
最近最久未使用页面置换算法(LRU)LRU算法是一种基于”最近使用原则”的页面置换算法。
它根据页面最近被访问的时间来选择被淘汰的页面。
当内存不足时,选择最长时间未被访问的页面进行置换,即将其从内存中移出。
LRU算法需要维护一个页面访问时间的记录,以便在需要置换时能够快速找到最近最久未使用的页面。
相比于FIFO算法,LRU算法更加合理地利用了页面的访问情况,但实现起来相对复杂一些。
模拟页面置换算法FIFO、LRU的实现
实验报告五实验名称:模拟页面置换算法FIFO、LRU的实现日期:2015-12-9 班级:13级计科学号:姓名:一、实验目的了解页面置换的概念,理解页面置换的算法加深对页面置换算法的理解。
二、实验内容Java编程语言实现FIFO和LUR页面算法。
三、项目要求与分析FIFO算法当需要置换页面时,主要通过置换最早进入内存的页面从而达到先进先出的目的。
LRU算法当需要置换页面时,主要通过置换进入内存中最久没有被访问的页面而达到最近最久未使用的目的。
程序中可以通过标志位进行记录。
四、具体实现1.FIFO算法实现代码以及运行结果:public class FIFO {/*** 内存块的个数*/public static int N ;/*** 内存块数组*/Object[] array = new Object[N];/*** 要访问的页面数组*/public static int[]visit;private int size;/*** 内存是非空为否* @return*/public boolean isEmpty() {if(0 == size)return true;elsereturn false;}/*** 内存是非空满* @return*/public boolean isFulled() {if(size >= N)return true;elsereturn false;}/*** 元素(页框)的个数* @return*/public int size() {return size;}/*** 查找元素o在数组中的位置* @param o* @return*/public int indexOfElement(Object o) { for(int i=0; i<N; i++) {if(o == array[i]) {return i;}}return -1;}/*** 页面转换* @param obj*/public Object trans(Object obj){Object e = null;int t = 0;if(indexOfElement(obj) != -1) {t = indexOfElement(obj);for(int i=t; i<size-1; i++) {array[i] = array[i+1];}array[size-1] = obj;} else {if(!isFulled()){array[size] = obj;size ++;} else {for(int i=0; i<size-1; i++) {array[i] = array[i+1];}array[size-1] = obj;}}if( -1 == t) {return null;} else {return array[t];}}/*** 输出内存区中的各数据*/public void showMemoryBlock() {for(int i=0; i<size; i++) {System.out.print(array[i] + " "); }}/*** 清空队列(页框)*/public void clear(){}/*** @param args*/public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.print("请输入内存块的数量:");N=sc.nextInt();System.out.print("请输入总页面数目:");int n=sc.nextInt();visit=new int[n];System.out.println("请输入各个页的页面号码:");for(int i=0;i<n;i++)visit[i]=sc.nextInt();FIFO fifo = new FIFO();for(int i=0; i<visit.length; i++) {fifo.trans(visit[i]);fifo.showMemoryBlock();System.out.println();}运行结果:2.LUR算法实现代码以及运行结果:public class LRU {static int volum;// 栈的容量static List<Integer>list=new LinkedList<Integer>();//链表用来模拟栈存放页面static int[]visit;//要访问的页面数组static int count=0;//记录缺页次数public static void main(String []args){Scanner sc = new Scanner(System.in);System.out.print("请输入栈的容量:");volum=sc.nextInt();System.out.print("请输入总页面数目:");int n=sc.nextInt();visit=new int[n];System.out.println("请输入各个页的页面号码:");for(int i=0;i<n;i++)visit[i]=sc.nextInt();sLRU();//调用最近最久未使用算法System.out.println("置换页面的数目为:"+count);}public static void sLRU(){int index=0;while(index<visit.length){boolean flag=false;if(list.size()<=volum){for(int i=0;i<list.size();i++){if((int)(list.get(i))==visit[index]){list.remove(i);//先删除list.add(visit[index]);//再添加到尾部flag=true;break;}}if(!flag){if(list.size()<volum){//如果栈未满,而且此页面没有在栈中,就将它入栈list.add(visit[index]);}else{//如果栈已经满了,且该页面号码没有在栈中,就把栈底元素删除,将新页插入int temp=list.get(0);list.remove(0);//最开始一个换出list.add(visit[index]);//加到末尾count++;System.out.println("开始换页了,将栈底的"+temp+"换出"); System.out.println("这也是没有办法的事情,毕竟栈是有限的");}}System.out.print("经过第"+(index+1)+"个页面的栈内容为");for(int k=0;k<list.size();k++)System.out.print(list.get(k)+" ");System.out.println();index++;}运行结果:五、所遇问题与解决方法问题:针对于FIFO算法定义选择在内存中驻留时间最久的页面予以淘汰,对于内存中的驻留时间理解复杂了不知道如何下手。
最佳页面置换算法例题
最佳页面置换算法例题
最佳页面置换算法是一种用于将一组页面按照某种规则进行页
边距和布局调整的算法。
下面是一个简单的例题,用于说明如何使用
最佳页面置换算法:
假设有一组文档,共10页,每页有4个页面。
每个页面的大小和
位置都已知,现在需要将这些文档按最佳页面置换算法进行调整,使
得每页的页面数量最少,页面距离最合理。
1. 确定每页需要的页面数量
每页需要的页面数量可以通过以下公式计算:
每页需要的页面数量 = (页数× 2 + 1) / 2
例如,第5页需要的页面数量为(5 × 2 + 1) / 2 = 8/2 = 4页。
2. 确定页面的位置和大小
接下来,需要确定每页应该包含哪些页面。
一种方法是从左到右,从上到下遍历每个页面,并在每个页面上标记出需要保留的页面数量。
例如,在第5页上,需要保留4个页面,所以标记为4个红色矩形。
另一种方法是使用布局算法来确定页面的位置和大小。
例如,可
以使用仿宋字体来设计一个布局,使得每页包含以下页面:第一页、第二页、第三页、第四页和第五页。
3. 调整文档布局
根据标记的数量和位置,使用最佳页面置换算法将文档进行布局
调整。
例如,对于上述例子,第5页应该包含以下页面:第一页、第二页、第三页、第四页和第五页。
4. 检查布局是否合理
最后,需要检查调整后的文档布局是否合理。
例如,如果在某个页面上使用了过多的页面,就需要重新调整页面数量或调整页面的位置。
最佳页面置换算法是一种常用的文档布局算法,可以帮助设计师
和开发人员高效地设计文档布局,提高文档的可读性和可用性。
页面置换算法模拟 实验报告
int select;
PRA test;
while(select)
{
cin>>select;
switch(select)
{
case 0:
break;
case 1:
cout<<"LRU算法结果如下:"<<endl;
test.LRU();
test.BlockClear();
3、实验要求
编程实现页面置换算法,最少实现两种算法,比较算法的优劣,并将调试结果显示在计算机屏幕上,并检测机算和笔算的一致性。
(1)采用页式分配存储方案,通过分别计算不同算法的命中率来比较算法的优劣,同时也考虑页面大小及内存实际容量对命中率的影响;
(2)实现OPT算法(最优置换算法)、LRU算法(Least Recently)、FIFO算法(First IN First Out)的模拟;
}
}
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)
{
for(int i=0; i<Bsize; i++)
{
block[i].content = -1;
block[i].timer = 0;
}
page = new pageInfor[Psize];
《操作系统》实验五:页面置换算法模拟
实验五. 请求页式存储管理的模拟[实验内容]:熟悉虚拟存储管理的各种页面置换算法,并编写模拟程序实现请求页式存储管理的页面置换算法----最近最久未使用算法(LRU),要求在每次产生置换时显示页面分配状态和缺页率。
[实验要求]:1、运行给出的实验程序,查看执行情况,进而分析算法的执行过程,在理解FIFO页面置换算法和最近最久未使用算法(LRU)置换算法后,给出最佳置换算法的模拟程序实现,并集成到参考程序中。
2、执行2个页面置换模拟程序,分析缺页率的情况。
最好页框数和访问序列长度可调节,在使用同一组访问序列数据的情况下,改变页框数并执行2个页面置换模拟程序,查看缺页率的变化。
3、在每次产生置换时要求显示分配状态和缺页率。
程序的地址访问序列通过随机数产生,要求具有足够的长度。
最好页框数和访问序列长度可调节。
实验的执行结果如下图所示(左下图为FIFO执行结果,右下图为LRU执行结果):程序源代码:#include <libio.h>#include "windows.h"#include <conio.h>#include <stdlib.h>#include <fstream.h>#include <io.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为不缺页,1为缺页pf_info.diseffect =0; // 缺页次数pf_info.flag =0; // 标志位,0表示无页面访问数据printf("\n请输入要分配的页框数:"); // 自定义分配的页框数scanf("%d",&pf);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("\n请输入要随机生成访问序列的长度:"); //自定义随机生成访问序列的长度scanf("%d",&pn);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 ; //随机数的大小在0-15之间 }}////////////////////////////////////////////////////////////////////////// 显示当前状态及缺页情况void displayinfo(void){int i,n;if(vpoint==0){printf("\n=============页面访问序列=============\n");for(i=0; i<pf_info.total_pn; i++){printf("%4d",pf_info.serial[i]);if ((i+1) % 10 ==0) printf("\n"); //每行显示10个}printf("\n======================================\n");}printf("访问%3d : 内存<",pf_info.serial[vpoint]);for(n=0;n<pf_info.total_pf;n++) // 页框信息{if (pageframe[n] >=0)printf("%3d",pageframe[n]);elseprintf(" ");}printf(" >");if(inpflag==1) //缺页标志,0为不缺页,1为缺页{printf(" ==>缺页 ");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] ++; // 访问历史加1}for(n=0;n<pf_info.total_pf;n++){if (pageframe[n]==page ){inpflag=0 ; //inpflag缺页标志,0为不缺页,1为缺页pagehistory[n]=0; //置访问历史为0return 1;}}inpflag=1; //页面不存在,缺页return 0;}//////////////////////////////////////////////////////////////////////// // FIFO页面置换算法void fifo(void){int n,count,pstate;rpoint=0; // 页面替换指针初始化为0invalidcount = 0; // 缺页数初始化为0createps(); // 随机生成访问序列count=0; // 是否装满是所有的页框for(n=0;n<pf_info.total_pf;n++) // 清除页框信息{pageframe[n]=-1;}inpflag=0; //缺页标志,0为不缺页,1为缺页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++; // 缺页次数加1}}Sleep(10);displayinfo(); // 显示当前状态} // 置换算法循环结束getch();return;}///////////////////////////////////////////////////////////////////// LRU页面置换算法void lru(void){int n,count,pstate,max;rpoint=0; // 页面替换指针invalidcount = 0; // 缺页次数初始化为0createps(); // 随机生成访问序列count=0; // 是否装满所有的页框for(n=0;n<pf_info.total_pf;n++){pageframe[n]=-1; // 清除页框信息pagehistory[n]=0; // 清除页框历史}inpflag=0; //缺页标志,0为不缺页,1为缺页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++; // 缺页次数加1}}Sleep(10);displayinfo(); // 显示当前状态} // 置换算法循环结束_getch();return;}/////////////////////最佳置换算法自己完成///////////////////////////////////////////////////////////////////// 主函数int main(){char ch;system("cls") ;while ( true ){printf("*******************************************\n");printf(" 若要执行FIFO页面置算法请按1\n");printf(" 若要执行LRU 页面置算法请按2\n");printf(" 若要退出请按3\n") ;printf("*******************************************\n");printf( "Enter your choice (1 or 2 or 3): ");do{ //如果输入信息不正确,继续输入ch = (char)getch() ;}while(ch != '1' && ch != '2'&& ch != '3');printf("\n\n你按的是:%c ,现在为你执行对应操作。
常用页面置换算法模拟实验
目录一、摘要 (3)二、正文 (4)三、设计总结 (8)四、参考文献 (10)五、附录:源程序代码 (11)摘要Windows中,为了提高内存利用率,提供了内外存进程对换机制;内存空间的分配和回收均以页为单位进行;一个进程只需将其一部分(段或页)调入内存便可运行;还支持请求调页的存储管理方式。
当进程在运行中需要访问某部分程序和数据时,发现其所在页面不在内存,就立即提出请求(向CPU发出缺页中断),由系统将其所需页面调入内存。
这种页面调入方式叫请求调页,为实现请求调页,核心配置了四种数据结构:页表、页框号、访问位、修改位、有效位、保护位等。
此设计为了了解Windows XP的操作接口及系统调用方式,熟悉Windows XP常用操作的实现过程,练习并掌握Visual C++开发环境。
利用Windows SDK(System Development Kit)提供的API(应用程序接口)设计一个虚拟存储管理程序,并使用最佳淘汰算法(OPT)、先进先出算法(FIFO)、最近最久未使用算法(LRU)计算访问命中率。
(命中率=1-页面失效次数/页地址流长度)。
关键字Windows;请求调页;数据结构;存储管理正文一、设计思路页面置换算法:当CPU接收到缺页中断信号,中断处理程序先保存现场,分析中断原因,转入缺页中断处理程序。
该程序通过查找页表,得到该页所在外存的物理块号。
如果此时内存未满,能容纳新页,则启动磁盘I/O将所缺之页调入内存,然后修改页表。
如果内存已满,则须按某种置换算法从内存中选出一页准备换出,是否重新写盘由页表的修改位决定,然后将缺页调入,修改页表。
利用修改后的页表,去形成所要访问数据的物理地址,再去访问内存数据。
整个页面的调入过程对用户是透明的。
此设计为了了解Windows XP的操作接口及系统调用方式,熟悉Windows XP常用操作的实现过程,练习并掌握Visual C++开发环境。
利用Windows SDK(System Development Kit)提供的API(应用程序接口)设计一个虚拟存储管理程序,并使用最佳淘汰算法(OPT)、先进先出算法(FIFO)、最近最久未使用算法(LRU)计算访问命中率。
实验五 请求页式存储管理中常用页面置换算法模拟
else { cout<<"---输入有误,物理块数请选择1-10的数---"<<endl<<"请输入分配的物理块数的大小:"; cin>>Nsize; } } break; case 2: cout<<"请输入分配的物理块数的大小: "; cin>>Nsize; while(1) { if(Nsize>0&&Nsize<=10) { Init(QString,Nsize); cout<<"页面号引用串: "; for(i=0;i<Psize;i++) { cout<<QString[i]<<" "; } cout<<endl; cout<<"LRU算法结果如下:"<<endl; LRU(Nsize); BlockClear(Nsize); cout<<"----------------------"<<endl; system("pause"); system("cls");
void BlockClear(int Nsize) {//块清除 for(int i=0; i<Nsize; i++) { block[i].yemian = -1; block[i].biaoji = 0; } } /*主程序*/ void main(void) { int i,select,Nsize,QString[Psize]={0}; while(select) { cout<<"页面号引用串: "; for(i=0;i<20;i++) { cout<<QString[i]<<" "; } cout<<endl; cout<<"+******************************+"<<endl; cout<<"+------------欢迎--------------+"<<endl; cout<<"+--------页面置换算法----------+"<<endl; cout<<"+-----选择<1>应用FIFO算法------+"<<endl; cout<<"+-----选择<2>应用LRU算法-------+"<<endl; cout<<"+-----选择<3>应用OPT算法-------+"<<endl; cout<<"+---选择<4>插入新的页面号引用串+"<<endl; cout<<"+-------选择<0>退出------------+"<<endl;
实验页面置换算法模拟实验ok
实验 5 页面置换算法模拟实验一.实验目地1.进一步掌握虚拟存储器地实现方法.2.掌握各种页面置换算法.3.比较各种页面置换算法地优缺点. 二.实验内容模拟实现页面置换算法, 步骤为:①使用产生随机数函数得到一个随机地数列, 作为将要载入地页面序列.②使用先进先出vFIFO)算法、最近最久未使用<LRU置换算法和最佳vOPT置换算法, 列出所需淘汰地页面号序列. b5E2RGbCAP③列出缺页中断次数. 三.参考源程序如下:#include vstdio.h> #include vstdlib.h> #include vtime.h> #define N 10 #define B 4/* ------------------------------------------------------ p1EanqFDPw函数名:IslnBuf(>,返回某个数X在不在缓冲Buf[],如在,返回位置,否则返回-1--- */ DXDiTa9E3dint IsInBuf(int buf[],int x>{int i,j=-1 。
for(i=0 o i<B。
i++>{ if(buf[i]==x>{ j=i 。
break 。
}else if(buf[i]==-1>{ buf[i]=x 。
j=i 。
break 。
} } return j 。
}/* ------------------------------------------------------ RTCrpUDGiT函数名:oldest(>, 返回最近最久未使用地页面位置--- */ 5PCzVD7HxAint oldest(int f[]>{int i,j=0,max=-1 。
for(i=0 。
ivB 。
i++>{ if(f[i]>max>{ max=f[i] 。
页面置换 操作系统实验报告
实验二页面置换算法实现一、实验目的(1)了解内存分页管理策略(2)掌握调页策略(3)掌握一般常用的调度算法(4)学会各种存储分配算法的实现方法。
(5)了解页面大小和内存实际容量对命中率的影响。
二、实验内容采用页式分配存储方案,通过分别计算不同算法的命中率来比较算法的优劣,同时也考虑页面大小及内存实际容量对命中率的影响,设计一个虚拟存储区和内存工作区,并使用下述算法来模拟实现页面的置换:1. 先进先出的算法(FIFO)2. 最近最久未使用算法(LRU)3. 最佳置换算法(OPT)实验分析在进程运行过程中,若其所访问的页面不存在内存而需要把它们调入内存,但内存已无空闲时,为了保证该进程能够正常运行,系统必须从内存中调出一页程序或数据送磁盘的对换区中。
但应调出哪个页面,需根据一定的算法来确定,算法的好坏,直接影响到系统的性能。
一个好的页面置换算法,应该有较低的页面更换频率。
2.1 先进先出(FIFO )页面置换算法当需要访问一个新的页面时,首先查看物理块中是否就有这个页面,若要查看的页面物理块中就有,则直接显示,不需要替换页面;如果要查看的页面物理块中没有,就需要寻找空闲物理块放入,若存在有空闲物理块,则将页面放入;若没有空闲物理块,则替换页面。
并将物理块中所有页面 timer++。
2.2 最近久未使用 (LRU) 置换算法的思路最近久未使用置换算法的替换规则,是根据页面调入内存后的使用情况来进行决策的。
该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间,当需淘汰一个页面的时候选择现有页面中其时间值最大的进行淘汰。
2.3 最佳(OPT)置换算法的思路其所选择的被淘汰的页面,是以后不使用的,或者是在未来时间内不再被访问的页面,采用最佳算法,通常可保证获得最低的缺页率。
三、实验流程3.1 系统功能图图3-1 系统功能图3.2 算法流程图1)先进先出(FIFO )页面置换算法流程图图3-2 先进先出页面置换算法流程图2)最近久未使用 (LRU) 置换算法图3-3 最近久未使用置换算法流程图3)最佳( OPT )置换算法图3-4 最佳置换算法流程图四、源程序#include<iostream.h>#include <stdlib.h>#include <time.h>#include <stdio.h>#define L 20 //页面长度最大为20int M; //内存块struct Pro//定义一个结构体{int num,time;};Input(int m,Pro p[L])//打印页面走向状态{cout<<"请输入页面长度(10~20):";do{cin>>m;if(m>20||m<10){ cout<<endl;cout<<"页面长度必须在10~20之间"<<endl<<endl;cout<<"请重新输入L:";}else break;}while(1);int i,j;j=time(NULL);//取时钟时间srand(j);//以时钟时间j为种子,初始化随机数发生器cout<<endl;cout<<"输出随机数: "<<endl;cout<<endl;for(i=0;i<m;i++){p[i].num=rand( )%10;//产生0到9之间的随机数放到数组p中p[i].time=0;cout<<p[i].num<<" ";}cout<<endl<<endl;return m;}void print(Pro *page1)//打印当前的页面{Pro *page=new Pro[M];page=page1;for(int i=0;i<M;i++)cout<<page[i].num<<" ";cout<<endl;}int Search(int e,Pro *page1 )//寻找内存块中与e相同的块号{Pro *page=new Pro[M];page=page1;for(int i=0;i<M;i++)if(e==page[i].num)return i;//返回i值return -1;}int Max(Pro *page1)//寻找最近最长未使用的页面{Pro *page=new Pro[M];page=page1;int e=page[0].time,i=0;while(i<M) //找出离现在时间最长的页面{if(e<page[i].time) e=page[i].time;i++;}for( i=0;i<M;i++)if(e==page[i].time)return i;//找到离现在时间最长的页面返回其块号return -1;}int Count(Pro *page1,int i,int t,Pro p[L])//记录当前内存块中页面离下次使用间隔长度{Pro *page=new Pro[M];page=page1;int count=0;for(int j=i;j<L;j++){if(page[t].num==p[j].num )break;//当前页面再次被访问时循环结束else count++;//否则count+1}return count;//返回count的值}int main(){int c;int m=0,t=0;float n=0;Pro p[L];m=Input(m,p);//调用input函数,返回m值cout<<"请输入分配的物理块m(2~6): ";cout<<endl<<endl;do{cin>>M;if(M>6||M<2){ cout<<endl;cout<<"物理块m必须在2~6之间"<<endl<<endl;cout<<"请重新输入m: ";}else break;}while(1);Pro *page=new Pro[M];do{for(int i=0;i<M;i++)//初始化页面基本情况{ page[i].num=0;page[i].time=m-1-i;}i=0;cout<<endl;cout<<"1:FIFO页面置换2:LRU页面置换"<<endl;cout<<"3:OPT页面置换4:退出"<<endl;cout<<"请选择页面置换算法:"<<endl;cin>>c;if(c==1)//FIFO页面置换{n=0;cout<<" FIFO算法页面置换情况如下: "<<endl;cout<<endl;while(i<m){if(Search(p[i].num,page)>=0) //当前页面在内存中{cout<<p[i].num<<" "; //输出当前页p[i].numcout<<"不缺页"<<endl;i++; //i加1}else //当前页不在内存中{if(t==M)t=0;else{n++; //缺页次数加1page[t].num=p[i].num; //把当前页面放入内存中cout<<p[i].num<<" ";print(page); //打印当前页面t++; //下一个内存块i++; //指向下一个页面}}}cout<<endl;cout<<"缺页次数:"<<n<<" 缺页率:"<<n/m<<endl<<endl; }if(c==2)//LRU页面置换{n=0;cout<<" LRU算法页面置换情况如下: "<<endl;cout<<endl;while(i<m){int a;t=Search(p[i].num,page);if(t>=0)//如果已在内存块中{ page[t].time=0;//把与它相同的内存块的时间置0 for(a=0;a<M;a++)if(a!=t)page[a].time++;//其它的时间加1cout<<p[i].num<<" ";cout<<"不缺页"<<endl;}else //如果不在内存块中{n++; //缺页次数加1t=Max(page); //返回最近最久未使用的块号赋值给tpage[t].num=p[i].num; //进行替换page[t].time=0; //替换后时间置为0cout<<p[i].num<<" ";print(page);for(a=0;a<M;a++)if(a!=t) page[a].time++; //其它的时间加1 }i++;}cout<<endl;cout<<"缺页次数:"<<n<<" 缺页率:"<<n/m<<endl<<endl; }if(c==3)//OPT页面置换{n=0;cout<<" OPT算法置换情况如下:"<<endl;cout<<endl;while(i<m){if(Search(p[i].num,page)>=0)//如果已在内存块中{cout<<p[i].num<<" ";cout<<"不缺页"<<endl;i++;}else//如果不在内存块中{int a=0;for(t=0;t<M;t++)if(page[t].num==0)a++;//记录空的内存块数if(a!=0) //有空内存{int q=M;for(t=0;t<M;t++)if(page[t].num==0&&q>t)q=t;//把空内存块中块号最小的找出来page[q].num=p[i].num;n++;cout<<p[i].num<<" ";print(page);i++;}else{int temp=0,s;for(t=0;t<M;t++)//寻找内存块中下次使用离现在最久的页面if(temp<Count(page,i,t,p)){temp=Count(page,i,t,p);s=t; }//把找到的块号赋给spage[s].num=p[i].num;n++;cout<<p[i].num<<" ";print(page);i++;}}}cout<<endl;cout<<"缺页次数:"<<n<<" 缺页率:"<<n/m<<endl<<endl;}if(c == 4) break;}while(c==1||c==2||c==3);return 0;}五、实验结果5.1 程序主界面运行程序后,将会提示用户输入页面长度,长度在10到20之间。
页面置换实验报告
计算机科学系实验报告书课程名:《操作系统》题目:虚拟存储器管理页面置换算法模拟实验班级:学号:姓名:一、实验目的与要求1.目的:请求页式虚存管理是常用的虚拟存储管理方案之一。
通过请求页式虚存管理中对页面置换算法的模拟,有助于理解虚拟存储技术的特点,并加深对请求页式虚存管理的页面调度算法的理解。
2.要求:本实验要求使用C语言编程模拟一个拥有若干个虚页的进程在给定的若干个实页中运行、并在缺页中断发生时分别使用FIFO和LRU算法进行页面置换的情形。
其中虚页的个数可以事先给定(例如10个),对这些虚页访问的页地址流(其长度可以事先给定,例如20次虚页访问)可以由程序随机产生,也可以事先保存在文件中。
要求程序运行时屏幕能显示出置换过程中的状态信息并输出访问结束时的页面命中率。
程序应允许通过为该进程分配不同的实页数,来比较两种置换算法的稳定性。
二、实验说明1.设计中虚页和实页的表示本设计利用C语言的结构体来描述虚页和实页的结构。
在虚页结构中,pn代表虚页号,因为共10个虚页,所以pn的取值范围是0—9。
pfn 代表实页号,当一虚页未装入实页时,此项值为-1;当该虚页已装入某一实页时,此项值为所装入的实页的实页号pfn。
time项在FIFO算法中不使用,在LRU中用来存放对该虚页的最近访问时间。
在实页结构中中,pn代表虚页号,表示pn所代表的虚页目前正放在此实页中。
pfn代表实页号,取值范围(0—n-1)由动态指派的实页数n所决定。
next是一个指向实页结构体的指针,用于多个实页以链表形式组织起来,关于实页链表的组织详见下面第4点。
2.关于缺页次数的统计为计算命中率,需要统计在20次的虚页访问中命中的次数。
为此,程序应设置一个计数器count,来统计虚页命中发生的次数。
每当所访问的虚页的pfn项值不为-1,表示此虚页已被装入某实页内,此虚页被命中,count加1。
最终命中率=count/20*100%。
3.LRU算法中“最近最久未用”页面的确定为了能找到“最近最久未用”的虚页面,程序中可引入一个时间计数器countime,每当要访问一个虚页面时,countime的值加1,然后将所要访问的虚页的time项值设置为增值后的当前countime值,表示该虚页的最后一次被访问时间。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
淮海工学院计算机科学系实验报告书课程名:《操作系统》题目:虚拟存储器管理页面置换算法模拟实验班级:学号:姓名:一、实验目的与要求1.目的:请求页式虚存管理是常用的虚拟存储管理方案之一。
通过请求页式虚存管理中对页面置换算法的模拟,有助于理解虚拟存储技术的特点,并加深对请求页式虚存管理的页面调度算法的理解。
2.要求:本实验要求使用C语言编程模拟一个拥有若干个虚页的进程在给定的若干个实页中运行、并在缺页中断发生时分别使用FIFO和LRU算法进行页面置换的情形。
其中虚页的个数可以事先给定(例如10个),对这些虚页访问的页地址流(其长度可以事先给定,例如20次虚页访问)可以由程序随机产生,也可以事先保存在文件中。
要求程序运行时屏幕能显示出置换过程中的状态信息并输出访问结束时的页面命中率。
程序应允许通过为该进程分配不同的实页数,来比较两种置换算法的稳定性。
二、实验说明1.设计中虚页和实页的表示本设计利用C语言的结构体来描述虚页和实页的结构。
在虚页结构中,pn代表虚页号,因为共10个虚页,所以pn的取值范围是0—9。
pfn代表实页号,当一虚页未装入实页时,此项值为-1;当该虚页已装入某一实页时,此项值为所装入的实页的实页号pfn。
time项在FIFO算法中不使用,在LRU中用来存放对该虚页的最近访问时间。
在实页结构中中,pn代表虚页号,表示pn所代表的虚页目前正放在此实页中。
pfn代表实页号,取值范围(0—n-1)由动态指派的实页数n所决定。
next是一个指向实页结构体的指针,用于多个实页以链表形式组织起来,关于实页链表的组织详见下面第4点。
2.关于缺页次数的统计为计算命中率,需要统计在20次的虚页访问中命中的次数。
为此,程序应设置一个计数器count,来统计虚页命中发生的次数。
每当所访问的虚页的pfn项值不为-1,表示此虚页已被装入某实页内,此虚页被命中,count加1。
最终命中率=count/20*100%。
3.LRU算法中“最近最久未用”页面的确定为了能找到“最近最久未用”的虚页面,程序中可引入一个时间计数器countime,每当要访问一个虚页面时,countime的值加1,然后将所要访问的虚页的time项值设置为增值后的当前countime值,表示该虚页的最后一次被访问时间。
当LRU算法需要置换时,从所有已分配实页的虚页中找出time值为最小的虚页就是“最近最久未用”的虚页面,应该将它置换出去。
4.算法中实页的组织因为能分配的实页数n是在程序运行时由用户动态指派的,所以应使用链表组织动态产生的多个实页。
为了调度算法实现的方便,可以考虑引入free和busy两个链表:free链表用于组织未分配出去的实页,首指针为free_head,初始时n个实页都处于free链表中;busy链表用于组织已分配出去的实页,首指针为busy_head,尾指针为busy_tail,初始值都为null。
当所要访问的一个虚页不在实页中时,将产生缺页中断。
此时若free链表不为空,就取下链表首指针所指的实页,并分配给该虚页。
若free链表为空,则说明n个实页已全部分配出去,此时应进行页面置换:对于FIFO 算法要将busy_head 所指的实页从busy链表中取下,分配给该虚页,然后再将该实页插入到busy 链表尾部;对于LRU算法则要从所有已分配实页的虚页中找出time值为最小的虚页,将该虚页从装载它的那个实页中置换出去,并在该实页中装入当前正要访问的虚页。
三、程序流程图四、主要程序清单#include "iostream.h"#include "malloc.h"#include "stdio.h"#include "string.h"#include "stdlib.h"#include "time.h"#define random(x) (rand()%x)typedef struct Node//实页结构{int pn;//虚页号int pfn;//实页号struct Node *next;}LinkQueueNode;typedef struct{LinkQueueNode *front;LinkQueueNode *rear;}LinkQueue;int h;int InitQueue(LinkQueue *Q)//初始化队列{Q->front=(LinkQueueNode *)malloc(sizeof(LinkQueueNode));if(Q->front!=NULL){Q->rear=Q->front;Q->front->next=NULL;return 1;}else return 0;}int EnterQueue(LinkQueue *Q,int p1,int p2)//入队{LinkQueueNode *NewNode;NewNode=(LinkQueueNode *)malloc(sizeof(LinkQueueNode));if(NewNode!=NULL){NewNode->pn=p1;NewNode->pfn=p2;NewNode->next=NULL;Q->rear->next=NewNode;Q->rear=NewNode;return 1;}else return 0;}void DeleteQueue(LinkQueue *Q)//删除链表内容,为空{LinkQueueNode *n;while(Q->front!=Q->rear){n=Q->front->next;Q->front->next=n->next;if(Q->rear==n)Q->rear=Q->front;free(n);}}int DeleteQueue(LinkQueue *Q,int a[10][3])//出队{int x;LinkQueueNode *n;if(Q->front==Q->rear){}else{n=Q->front->next;Q->front->next=n->next;x=n->pfn;a[n->pn][1]=-1;if(Q->rear==n)Q->rear=Q->front;free(n);}return x;}LinkQueue* FIFO(LinkQueue *free,LinkQueue *busy,int r[],int a[10][3])//先进先出页面置换算法,返回busy链表{LinkQueueNode *s,*p;int b,count=0;//存储虚页号for(int x=0;x<h;x++)//对虚页访问{int q=0;s=busy->front;p=busy->front;b=r[x];//遍历busy链表,当链表中存在要访问的虚页时不置换退出,不存在时置换while(s->next!=NULL){s=s->next;if(s->pn==b){q=1;count++;break;}}if(q==0)//没有退出,则为不存在,若free链表存在空实页,则分配,否则Busy链表先队首出队,在把虚页信息节点排在队尾{if(free->front!=free->rear){a[b][1]=DeleteQueue(free,a);EnterQueue(busy,a[b][0],a[b][1]);}else{cout<<"被置换"<<busy->front->next->pn<<" "<<busy->front->next->pfn<<endl;a[b][1]=DeleteQueue(busy,a);//实页号赋值EnterQueue(busy,a[b][0],a[b][1]);//入队cout<<"置换"<<a[b][0]<<" "<<a[b][1]<<endl;}}cout<<"实页号虚页号"<<endl;while(p->next!=NULL)//输出实页虚页分配情况{p=p->next;cout<<p->pfn<<" "<<p->pn<<endl;}}cout<<"命中次数="<<count<<" 命中率="<<((float)count/h)*100<<"% 缺页率="<<((float)(20-count)/h)*100<<"%"<<endl;DeleteQueue(busy);//使busy链表内容为空return busy;}LinkQueue* LRU(LinkQueue *free,LinkQueue *busy,int r[],int a[10][3])//最近最久未使用置换算法,返回busy链表{LinkQueueNode *s,*p,*m;int b,count=0,counttime=0;//存储虚页号for(int x=0;x<h;x++)//对虚页访问{counttime++;int q=0;s=busy->front;p=busy->front;b=r[x];//遍历busy链表,当链表中存在要访问的虚页时不置换退出,不存在时置换while(s->next!=NULL){s=s->next;if(s->pn==b){q=1;a[b][2]=counttime;count++;break;}}if(q==0)//不存在,若free链表存在空实页,则分配,否则Busy链表先队首出队,在把虚页信息节点排在队尾{if(free->front!=free->rear){a[b][1]=DeleteQueue(free,a);EnterQueue(busy,a[b][0],a[b][1]);a[b][2]=counttime;}else{m=busy->front->next;s=busy->front;while(s->next!=NULL)//至少有两个结点{s=s->next;if(a[s->pn][2]>a[m->pn][2]){}//该实页号结点被置换else{m=s;}}a[m->pn][1]=-1;cout<<"被置换"<<a[m->pn][0]<<" "<<a[m->pn][1]<<" "<<a[m->pn][2]<<endl;m->pn=b;a[b][1]=m->pfn;a[b][2]=counttime;cout<<"置换"<<a[b][0]<<" "<<a[b][1]<<" "<<a[b][2]<<endl;}}cout<<"实页号虚页号"<<endl;while(p->next!=NULL)//输出实页虚页分配情况{p=p->next;cout<<p->pfn<<" "<<p->pn<<endl;}}cout<<"命中次数="<<count<<" 命中率="<<((float)count/h)*100<<"% 缺页率="<<((float)(20-count)/h)*100<<"%"<<endl;DeleteQueue(busy);//使busy链表内容为空return busy;}int r[20];//随机产生虚页访问顺序int main(){int m,n,i,j,y,x;inta[10][3]={{0,-1,0},{1,-1,0},{2,-1,0},{3,-1,0},{4,-1,0},{5,-1,0},{6,-1,0},{7,-1,0},{8,-1,0},{9,-1,0}};int b[10][3];cout<<"实页数:";cin>>n;//初始化链表free,busyLinkQueue* free,*busy;free=(LinkQueue *)malloc(sizeof(LinkQueue));busy=(LinkQueue *)malloc(sizeof(LinkQueue));InitQueue(busy);//10个虚页,包括虚页号、实页号、最近访问时间cout<<"1.先进先出 2.最近最久未使用 3.输入虚页访问顺序 4.重置实页数其它:退出(请先输入虚页访问顺序,此程序的虚页为10页,不可更改,序号为0~9)"<<endl<<"请输入选项:";cin>>m;while(m==1||m==2||m==3||m==4){switch(m){case 1:if(h!=0){cout<<"FIFO:"<<endl;for(i=0;i<10;i++)for(j=0;j<3;j++){b[i][j]=a[i][j];}InitQueue(free);for(y=0;y<n;y++)//将实页数装入free链表{EnterQueue(free,-1,y);}busy=FIFO(free,busy,r,b);//链表内容为空,所以不影响下一次使用}else{cout<<"先输入虚页访问顺序,即选项3"<<endl;}break;case 2:if(h!=0){cout<<"LRU:"<<endl;for(i=0;i<10;i++)for(j=0;j<3;j++){b[i][j]=a[i][j];}InitQueue(free);for(y=0;y<n;y++)//将实页数装入free链表{EnterQueue(free,-1,y);}busy=LRU(free,busy,r,b);}else{cout<<"先输入虚页访问顺序,即选项3"<<endl;}break;case 3:cout<<"访问虚页的次数:(最多为20次)";cin>>h;if(h>20){cout<<"超出设定次数!"<<endl;break;}cout<<h<<"次访问虚页顺序为:";cout<<"1.随机 2.手动 "<<endl<<"请输入选项:";cin>>m;switch(m){case 1:srand((int)time(0));for(x=0;x<h;x++){r[x]=random(10);cout<<r[x]<<" ";}break;case 2:for(x=0;x<h;x++){cin>>r[x];}break;default:cout<<"输入选项不正确,请重新输入:";cin>>m;break;}cout<<endl;break;case 4:cout<<"实页数:";cin>>n;break;default:break;}cout<<"请输入所选项:";cin>>m;}return 0;}五、程序运行结果实页数为3,采用得是手动输入方式实页数为3,采用的是随机生成方式六、实验体会已经是第三次写实验了,这三次都是用C++来编写的,其实每次的上机实验都能够很好对我们上课的理论知识进行巩固。