页面置换算法实验报告材料
页面置换算法模拟实验报告材料

实验编号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。
LRU页面置换算法的设计实验报告

return-1;
}
intfindReplace(intBsize)
{//查找应予置换的页面
intpos = 0;
for(inti=0; i<Bsize; i++)
if(block[i].timer >= block[pos].timer)
for(i=0;i<20;i++)
{
QString[i] = rand()%10 ;
}
cout<<"页面号引用串: ";
for(i=0;i<20;i++)
{
cout<<QString[i]<<" ";
}
cout<<endl<<"------------------------------------------------------"<<endl;
四、实验结果(含程序、数据记录及分析和实验总结等)
#include<iostream>
#include<string>
#include<stdlib.h>
#include<ctime>
usingnamespacestd;
constintBsize=10;
constintPsize=20;
structp
Bsize = 3;
Init(QString,Bsize);
cout<<"LRU算法结果如下:<<endl;
操作系统实验三(页面置换算法)实验报告材料

实验三实验报告实验源码:#include "stdio.h"#include <iostream.h>#include <stdlib.h>#define DataMax 100 // 常量DataMax#define BlockNum 10 // 常量BlockNumint DataShow[BlockNum][DataMax]; // 用于存储要显示的数组bool DataShowEnable[BlockNum][DataMax]; // 用于存储数组中的数据是否需要显示int Data[DataMax]; // 保存数据int Block[BlockNum]; // 物理块int count[BlockNum]; // 计数器int N; // 页面个数int M; // 最小物理块数int ChangeTimes; // 缺页次数void DataInput(); // 输入数据的函数void DataOutput(); // 输出数据的函数void FIFO(); // FIFO 函数void Optimal(); // Optimal函数void LRU(); // LRU函数int main(int argc, char* argv[]){DataInput();int menu;while(true){printf("\n* 菜单选择 *\n");printf("*******************************************************\n");printf("* 1-Optimal *\n");printf("* 2-FIFO *\n");printf("* 3-LRU *\n");printf("* 4-返回上一级 *\n");printf("* 0-EXIT *\n");printf("*******************************************************\n");scanf("%d",&menu);switch(menu){case 1:Optimal();break;case 2:FIFO();break;case 3:LRU();break;case 0:exit(0);break;case 4:system("cls");DataInput();break;}if(menu != 1 && menu != 2 && menu != 3 && menu != 0 && menu !=4) { system("cls");printf("\n请输入0 - 4之间的整数!\n");continue;}}return 0;}void DataInput(){int i,choice;printf("请输入最小物理块数:");scanf("%d",&M);// 输入最小物理块数大于数据个数while(M > BlockNum){printf("物理块数超过预定值,请重新输入:");scanf("%d",&M);}printf("请输入页面的个数:");scanf("%d",&N);// 输入页面的个数大于数据个数while(N > DataMax){printf("页面个数超过预定值,请重新输入:");scanf("%d",&N);}printf("请选择产生页面访问序列的方式(1.随机 2.输入):");scanf("%d",&choice);switch(choice){case 1:// 产生随机访问序列for(i = 0;i < N;i++){Data[i] = (int)(((float) rand() / 32767) * 10); // 随机数大小在0 - 9之间}system("cls");// 显示随机产生的访问序列printf("\n随机产生的访问序列为:");for(i = 0;i < N;i++){printf("%d ",Data[i]);}printf("\n");break;case 2:// 输入访问序列printf("请输入页面访问序列:\n");for(i = 0;i < N;i++)scanf("%d",&Data[i]);system("cls");// 显示输入的访问序列printf("\n输入的访问序列为:");for(i = 0;i < N;i++){printf("%d ",Data[i]);}printf("\n");break;default:while(choice != 1 && choice != 2){printf("请输入1或2选择相应方式:");scanf("%d",&choice);}break;}}void DataOutput(){int i,j;// 对所有数据操作for(i = 0;i < N;i++){printf("%d ",Data[i]);}printf("\n");for(j = 0;j < M;j++){// 对所有数据操作for(i = 0;i < N;i++){if( DataShowEnable[j][i] )printf("%d ",DataShow[j][i]);elseprintf(" ");}printf("\n");}printf("缺页次数: %d\n",ChangeTimes);printf("缺页率: %d %%\n",ChangeTimes * 100 / N); }// 最佳置换算法void Optimal(){int i,j,k;bool find;int point;int temp; // 临时变量,比较离的最远的时候用int m = 1,n;ChangeTimes = 0;for(j = 0;j < M;j++){for(i=0;i < N;i++)DataShowEnable[j][i] = false; // 初始化为false,表示没有要显示的数据}}for(i = 0;i < M;i++){count[i] = 0 ; // 初始化计数器}// 确定当前页面是否在物理块中,在继续,不在置换/////////////////////////////////////////////////////////////////////////// ////////Block[0] = Data[0];for(i = 1;m < M;i++){int flag = 1;for(n = 0; n < m;n++){if(Data[i] == Block[n]) flag = 0;}if(flag == 0) continue;Block[m] = Data[i];m++;}/////////////////////////////////////////////////////////////////////////// ///////// 对所有数据进行操作for(i=0;i < N;i++){// 表示块中有没有该数据find = false;for(j = 0;j < M;j++){if( Block[j] == Data[i] ){find = true;}}if( find ) continue; // 块中有该数据,判断下一个数据// 块中没有该数据,最优算法ChangeTimes++; // 缺页次数++for(j = 0;j < M;j++)// 找到下一个值的位置find = false;for( k = i;k < N;k++){if( Block[j] == Data[k] ){find = true;count[j] = k;break;}}if( !find ) count[j] = N;}// 因为i是从0开始记,而BlockNum指的是个数,从1开始,所以i+1if( (i + 1) > M ){//获得要替换的块指针temp = 0;for(j = 0;j < M;j++){if( temp < count[j] ){temp = count[j];point = j; // 获得离的最远的指针}}}else point = i;// 替换Block[point] = Data[i];// 保存要显示的数据for(j = 0;j < M;j++){DataShow[j][i] = Block[j];DataShowEnable[i < M ? (j <= i ? j : i) : j][i] = true; // 设置显示数据}}// 输出信息printf("\nOptimal => \n");DataOutput();// 先进先出置换算法void FIFO(){int i,j;bool find;int point;int temp; // 临时变量int m = 1,n;ChangeTimes = 0;for(j = 0;j < M;j++){for(i = 0;i < N;i++){DataShowEnable[j][i] = false; // 初始化为false,表示没有要显示的数据}}for(i = 0;i < M;i++){count[i] = 0; // 大于等于BlockNum,表示块中没有数据,或需被替换掉// 所以经这样初始化(3 2 1),每次替换>=3的块,替换后计数值置1,// 同时其它的块计数值加1 ,成了(1 3 2 ),见下面先进先出程序段}// 确定当前页面是否在物理块中,在继续,不在置换/////////////////////////////////////////////////////////////////////////// ////////Block[0] = Data[0];for(i = 1;m < M;i++){int flag = 1;for(n = 0; n < m;n++){if(Data[i] == Block[n]) flag = 0;}if(flag == 0) continue;Block[m] = Data[i];m++;}/////////////////////////////////////////////////////////////////////////// ///////// 对有所数据操作for(i = 0;i < N;i++){// 增加countfor(j = 0;j < M;j++){count[j]++;}find = false; // 表示块中有没有该数据for(j = 0;j < M;j++){if( Block[j] == Data[i] ){find = true;}}// 块中有该数据,判断下一个数据if( find ) continue;// 块中没有该数据ChangeTimes++; // 缺页次数++// 因为i是从0开始记,而M指的是个数,从1开始,所以i+1 if( (i + 1) > M ){//获得要替换的块指针temp = 0;for(j = 0;j < M;j++){if( temp < count[j] ){temp = count[j];point = j; // 获得离的最远的指针}}}else point = i;// 替换Block[point] = Data[i];count[point] = 0; // 更新计数值// 保存要显示的数据for(j = 0;j < M;j++){DataShow[j][i] = Block[j];DataShowEnable[i < M ? (j <= i ? j : i) : j][i] = true; // 设置显示数据}}// 输出信息printf("\nFIFO => \n");DataOutput();}// 最近最久未使用置换算法void LRU(){int i,j;bool find;int point;int temp; // 临时变量int m = 1,n;ChangeTimes = 0;for(j = 0;j < M;j++){for(i = 0;i < N;i++){DataShowEnable[j][i] = false; // 初始化为false,表示没有要显示的数据}}for(i = 0;i < M;i++){count[i] = 0 ; // 初始化计数器}// 确定当前页面是否在物理块中,在继续,不在置换/////////////////////////////////////////////////////////////////////////// ////////Block[0] = Data[0];for(i = 1;m < M;i++){int flag = 1;for(n = 0; n < m;n++){if(Data[i] == Block[n]) flag = 0;}if(flag == 0) continue;Block[m] = Data[i];m++;}/////////////////////////////////////////////////////////////////////////// ///////// 对有所数据操作for(i = 0;i < N;i++){// 增加countfor(j = 0;j < M;j++){count[j]++;}find = false; // 表示块中有没有该数据for(j = 0;j < M;j++){if( Block[j] == Data[i] ){count[j] = 0;find = true;}}// 块中有该数据,判断下一个数据if( find ) continue;// 块中没有该数据ChangeTimes++;// 因为i是从0开始记,而BlockNum指的是个数,从1开始,所以i+1if( (i + 1) > M ){//获得要替换的块指针temp = 0;for(j = 0;j < M;j++){if( temp < count[j] ){temp = count[j];point = j; // 获得离的最远的指针}}}else point = i;// 替换Block[point] = Data[i];count[point] = 0;// 保存要显示的数据for(j=0;j<M;j++){DataShow[j][i] = Block[j];DataShowEnable[i < M ?(j <= i ? j : i) : j][i] = true; // 设置显示数据}}// 输出信息printf("\nLRU => \n");DataOutput();}实验结果截图:程序运行:输入相应数据:选择相应算法:最佳置换算法:先进先出算法:最近最久未使用算法:。
页面置换算法实验报告_4

页面置换算法实验报告院系:****************学院班级:***********姓名:***学号:************一、实验题目: 页面置换算法二. 实验目的:1.用C语言编写OPT、FIFO、LRU三种置换算法。
2.熟悉内存分页管理策略。
3.了解页面置换的算法。
4.掌握一般常用的调度算法。
5.根据方案使算法得以模拟实现。
6.锻炼知识的运用能力和实践能力。
三. 实验内容及要求:设计一个虚拟存储区和内存工作区, 编程序演示下述算法的具体实现过程, 并计算访问命中率:要求设计主界面以灵活选择某算法, 且以下算法都要实现1) 最佳置换算法(OPT): 将以后永不使用的或许是在最长(未来)时间内不再被访问的页面换出。
2) 先进先出算法(FIFO):淘汰最先进入内存的页面, 即选择在内存中驻留时间最久的页面予以淘汰。
3) 最近最久未使用算法(LRU): 淘汰最近最久未被使用的页面。
四、实验结果初始化结果1, 先进先出(FIFO)算法实验结果:2, 最近最久未使用(LRU)算法实验结果: 3, 最佳使用法(OPT)实验结果:五、实验总结选择置换算法, 先输入所有页面号, 为系统分配物理块, 依次进行置换:OPT基本思想:是用一维数组page[]存储页面号序列, memery[]是存储装入物理块中的页面。
数组next[]记录物理块中对应页面的最后访问时间。
每当发生缺页时, 就从物理块中找出最后访问时间最大的页面, 调出该页, 换入所缺的页面。
若物理块中的页面都不再使用, 则每次都置换物理块中第一个位置的页面。
FIFO基本思想:是用队列存储内存中的页面, 队列的特点是先进先出, 与该算法是一致的, 所以每当发生缺页时, 就从队头删除一页, 而从队尾加入缺页。
或者借助辅助数组time[]记录物理块中对应页面的进入时间, 每次需要置换时换出进入时间最小的页面。
LRU基本思想:是用一维数组page[]存储页面号序列, memery[]是存储装入物理块中的页面。
页面置换算法实验报告

页面置换算法实验报告
一、实验内容
本次实验主要围绕页面置换算法进行,以实验课本的实例介绍,采用FIFO页面置换算法对后面提到的参数进行置换,最终得出页面置换的结果和比较所得结果。
二、实验步骤
(一) 熟悉FIFO算法
首先是要了解FIFO页面置换算法,FIFO全称(First In First Out),按页面进入内存的顺序来替换相应内存页面,先进先出,将先进入内存的页面先替换出去。
(二) 阅读实验课本
在阅读实验课本之前要先熟悉实验书上所介绍的FIFO算法,然后在实验书上找出需要做的实验,并对实验环境和表格进行观察,掌握实验的基本内容。
(三) 开始页面置换
在开始实验之前,熟悉实验环境,根据实验书上的参数,首先模拟进程分配内存,根据FIFO算法去进行计算,根据上表中的参数去比较,最后得出最终结果。
(四) 在本次实验的补充
这次实验中,可以把FIFO的概念应用到实际应用中,也可以模拟不同情况,例如改变页面的大小,观察不同页面置换算法的结果,实验出最合适的结果。
三、实验结论
本次实验是为了了解FIFO页面置换算法,实验出最终的结果,最后得出页面置换的结果及比较结果。
【精品】页面置换算法实验报告

【精品】页面置换算法实验报告一、实验目的了解操作系统中的页面置换算法,并实现FIFO、LRU和Clock算法。
二、实验原理页面置换算法是操作系统中用到的一种算法,其作用是在内存不够用时,选择牺牲已经在内存中的一些页,腾出更多的空间给新的内容。
本次实验主要实现了FIFO、LRU和Clock算法。
1、FIFO算法FIFO算法是最简单的页面置换算法,它采用先进先出的原则,即最先进入内存的页面应该最早被替换出去。
该算法的实现非常简单,只需要维护一个队列即可。
当需要置换页面时,选择队列的第一个页面进行替换即可。
2、LRU算法LRU算法是Least Recently Used的缩写,即最近最少使用算法。
该算法的核心思想是选择最久没有被使用的页面进行替换。
为了实现该算法,需要维护记录页面使用时间的链表、栈或队列等结构。
3、Clock算法Clock算法也叫做二次机会算法,是一种改良的FIFO算法。
它是基于FIFO算法的思想,并且每个页面都设置了一个使用位(use bit),用于记录该页面是否被使用过。
当需要置换一个页面时,检查该页面的使用位,如果该页面的使用位为1,则将该页面的使用位设置为0并移到队列的末尾,表示该页面有“二次机会”继续待在内存中;如果该页面的使用位为0,则选择该页面进行替换。
三、实验过程本次实验采用Python语言实现页面置换算法,并使用样例进行测试。
1、FIFO算法实现FIFO算法的实现非常简单,只需要用一个队列来维护已经在内存中的页面,当需要置换页面时,选择队列的第一个元素即可。
代码如下:```pythonfrom collections import dequeclass FIFO:def __init__(self, frame_num):self.frame_num = frame_numself.frames = deque(maxlen=frame_num)def access(self, page):if page in self.frames:return Falseif len(self.frames) >= self.frame_num:self.frames.popleft()self.frames.append(page)return True```2、LRU算法实现LRU算法的实现需要维护一个记录页面使用时间的链表或队列。
页面置换实验报告
计算机科学系实验报告书课程名:《操作系统》题目:虚拟存储器管理页面置换算法模拟实验班级:学号:姓名:一、实验目的与要求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、最佳淘汰算法(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。
页面置换实习报告
页面置换实习报告在计算机系统中,页面置换是一项至关重要的内存管理技术。
为了更深入地理解和掌握这一技术,我进行了相关的实习。
一、实习目的页面置换的目的在于当内存空间不足时,将一些暂时不使用的页面换出到外存,以腾出空间给当前需要的页面。
通过这次实习,我希望能够:1、深入理解页面置换算法的工作原理和特点。
2、掌握不同算法在实际应用中的性能差异。
3、提高自己的编程能力和问题解决能力。
二、实习环境本次实习使用的编程语言为 Python,开发环境为 PyCharm。
操作系统为 Windows 10。
三、页面置换算法简介1、先进先出(FIFO)算法FIFO 算法是最简单的页面置换算法之一。
它总是淘汰最先进入内存的页面。
这种算法实现简单,但可能会导致一些频繁使用的页面被过早置换出去。
2、最近最久未使用(LRU)算法LRU 算法根据页面最近的使用情况来决定置换。
即淘汰最长时间未被使用的页面。
该算法性能较好,但实现相对复杂,需要记录页面的使用时间。
3、最优置换(OPT)算法OPT 算法是一种理论上的最优算法,它淘汰未来最长时间内不会被使用的页面。
然而,由于在实际中无法准确预测未来的页面使用情况,所以该算法更多地用于理论分析。
四、实习过程1、算法实现首先,我使用 Python 实现了上述三种页面置换算法。
在实现过程中,我使用了数据结构来存储页面的相关信息,并通过模拟页面的调入和调出过程来计算缺页次数。
以 FIFO 算法为例,我使用一个队列来存储页面进入内存的顺序。
当需要置换页面时,将队首的页面淘汰。
2、性能测试为了比较不同算法的性能,我设计了一系列的测试用例。
测试用例包括不同的页面访问序列和不同的内存大小。
通过运行测试用例,我记录了每种算法在不同情况下的缺页次数。
3、结果分析对测试结果进行分析是实习的重要环节。
我发现,在不同的页面访问模式下,不同算法的表现差异较大。
例如,当页面访问序列具有局部性时,LRU 算法的表现通常优于FIFO 算法。
页面置换算法实验报告
操作系统实验报告——页面置换问题的实现系别:信息工程系班级:计科姓名:学号:页面置换问题的模拟实现一.实验目的1.通过模拟实现几种基本页面置换的算法,了解虚拟存储技术的特点。
2.掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想,并至少用三种算法来模拟实现。
3.通过对几种置换算法页面的比较,来对比他们的优缺点,并通过比较更换频率来对比它们的效率。
二.实验内容:设计一个虚拟存储区和内存工作区,并使用下述算法来模拟实现页面的置换:1. 先进先出的算法(FIFO)2. 最近最久未使用算法(LRU)3. 最佳置换算法(OPT)三.实验分析在进程运行过程中,若其所访问的页面不存在内存而需要把它们调入内存,但内存已无空闲时,为了保证该进程能够正常运行,系统必须从内存中调出一页程序或数据送磁盘的对换区中。
但应调出哪个页面,需根据一定的算法来确定,算法的好坏,直接影响到系统的性能。
一个好的页面置换算法,应该有较低的页面更换频率。
假设分给一作业的物理块数为3 ,页面数为20个。
页面号为(20个):7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,11.先进先出(FIFO)置换算法的思路该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。
该算法实现简单,只需把一个进程已调入内存的页面,按照先后次序连接成一个队列,并设置一个替换指针,使它总指向最老的页面。
2.最近久未使用(LRU)置换算法的思路最近久未使用置换算法的替换规则,是根据页面调入内存后的使用情况来进行决策的。
该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间,当需淘汰一个页面的时候选择现有页面中其时间值最大的进行淘汰。
3.最佳(OPT)置换算法的思路其所选择的被淘汰的页面,奖是以后不使用的,或者是在未来时间内不再被访问的页面,采用最佳算法,通常可保证获得最低的缺页率。
4.数据结构struct pageInfor{int content;//页面号int timer;//被访问标记};class PRA{public:PRA(void);int findSpace(void); //查找是否有空闲内存int findExist(int curpage); //查找内存中是否有该页面int findReplace(void); //查找应予置换的页面void display(void); //显示void FIFO(void); //FIFO算法void LRU(void); //LRU算法void BlockClear(void);//BLOCK清空,以便用另一种方法重新演示pageInfor * block; //物理块pageInfor * page; //页面号串private:};5.FIFO页面置换算法当需要访问一个新的页面时,首先调用findExist(i)函数来查看物理块中是否就有这个页面,若要查看的页面物理块中就有,则调用display函数直接显示,不需要替换页面;如果要查看的页面物理块中没有,就需要寻找空闲物理块放入,若存在有空闲物理块,则将页面放入;若没有空闲物理块,则调用findReplace 函数替换页面。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
页面置换算法实验报告一、实验目的:设计和实现最佳置换算法、随机置换算法、先进先出置换算法、最近最久未使用置换算法、简单Clock置换算法及改进型Clock置换算法;通过支持页面访问序列随机发生实现有关算法的测试及性能比较。
二、实验内容:●虚拟内存页面总数为N,页号从0到N-1●物理内存由M个物理块组成●页面访问序列串是一个整数序列,整数的取值范围为0到N - 1。
页面访问序列串中的每个元素p表示对页面p的一次访问●页表用整数数组或结构数组来表示❑符合局部访问特性的随机生成算法1.确定虚拟内存的尺寸N,工作集的起始位置p,工作集中包含的页数e,工作集移动率m(每处理m个页面访问则将起始位置p +1),以及一个范围在0和1之间的值t;2.生成m个取值范围在p和p + e间的随机数,并记录到页面访问序列串中;3.生成一个随机数r,0 ≤ r ≤ 1;4.如果r < t,则为p生成一个新值,否则p = (p + 1) mod N;5.如果想继续加大页面访问序列串的长度,请返回第2步,否则结束。
三、实验环境:操作系统:Windows 7软件:VC++6.0四、实验设计:本实验包含六种算法,基本内容相差不太,在实现方面并没有用统一的数据结构实现,而是根据不同算法的特点用不同的数据结构来实现:1、最佳置换和随机置换所需操作不多,用整数数组模拟内存实现;2、先进先出置换和最近最久未使用置换具有队列的特性,故用队列模拟内存来实现;3、CLOCK置换和改进的CLOCK置换具有循环队列的特性,故用循环队列模拟内存实现;4、所有算法都是采用整数数组来模拟页面访问序列。
五、数据结构设计://页面访问序列数组:int ref[ref_size];//内存数组:int phy[phy_size];//队列数据结构定义:typedef struct QNode //定义队列数据结构{int data;struct QNode *next;}QNode,*QueuePtr;typedef struct{QueuePtr front; //头指针QueuePtr rear; //尾指针}LinkQueue;//定义链表数据结构typedef struct LNode //定义循环链表数据结构{int data;int flag; //访问位int modify; //修改位struct LNode *next;}LNode,*LinkList;六、主要函数说明:1、void set_rand_num() //产生具有局部特性的随机数列;2、int Exchange_LNode(LinkList &L,int e,int i)//将链表L中序号为i的结点替换为内容为e的结点;3、bool Search_LinkList(LinkList &L,int e,int &i)//找到链表L中内容为e的结点,并用i返回其位置,i=1表示第一个非头结点,依次类推;4、void Search_LL_Flag(LinkList &L,int &i)//用i返回第一个flag为0的结点的位置,i=1表示第一个非头结点,以此类推;5、void Set_LL_Flag(LinkList &L,int i) //设置链表L中的序号为i的结点的flag标志为1;6、int Search_LL_ModifyClock(LinkList &L,int &modify_num)//找到改进的CLOCK算法所需要淘汰的页,用modify_num返回其位置;此函数根据书上给的思路,第一遍扫描A=0且M=0的页面予以淘汰,若失败,则进行第二轮扫描A=0且M=1的页面,第二轮扫描时将所有访问过的页面的访问位A置0;若失败则重复上述两部;7、void Set_LL_modify(LinkList &L,int i) //设置链表L中的序号为i的结点的modify标志为1;8、bool SearchQueue(LinkQueue &Q,int e,int &i) //寻找队列Q中结点data域等于e的结点,并用i返回其在Q中的位置;9、int getnum(int a,int b) //用b返回元素a在被引用数列中的下一个位置10、void ORA() //实现最佳置换算法,包括判断页面是否在内存中、页面进内存、输出内存状态等内容;11、void RAND() //随机置换算法12、void FIFO() //先进先出算法13、void LRU() //最近最久未使用算法实现最近最久未使用算法的思想是:判断待进入内存的页面,如果与内存中的第一个页面相同,则将它移到最后一个,即标志为最近使用的页;如果与内存中的第二个页面相同,则将它删除,并在队列尾部添加相同元素,即标志为最近使用的页;14、void CLOCK() //实现CLOCK算法15、void Modified_Clock() //实现改进的CLOCK算法16、int main() //主函数,调用实现各算法的6个主要函数,并输出各算法的缺页率。
七、实验问题回答:1、FIFO算法是否比随机置换算法优越?答:FIFO算法比随机置换算法优越,但优势并不明显。
2、LRU算法比FIFO 算法优越多少?答:LRU算法FIFO算法的效率要高5%-10%,有理论知识可知,页面访问序列具有局部性,而FIFO 算法并不符合实际情况。
3、LRU算法和Optimal算法有何差距?答:LRU算法是所有算法中效率最接近Optimal算法的算法,由理论知识可知,Optimal算法是理想的算法,现实中几乎不可能实现,只能作为一种测评标准,LRU算法是效率较高的可实现置换算法,但其硬件要求较高,如果规模较小,则略显麻烦。
4、Clock算法和LRU算法有何差距?答:Clock算法和LRU算法从结果看来差距不大,Clock算法是使用软件的方式实现LRU算法中硬件的功能,从而在执行效率上会稍逊色些。
八、实验过程结果截图:实验结果截图测评一:测评二:测评三:实验过程截图(注:只截取第三次测评,蓝色字体表示产生缺页中断)九、实验结果分析:1、最佳置换算法效果最佳不论在那组数据中,最佳置换算法的效果都是最好的,且都会比其它算法的性能高出不少。
但通过课堂上的学习,我们知道这只是一种理想化算法,但实际上却难于实现,故主要用于算法评价参照。
2、随机算法的性能总是最不好的这是由于随机算法每次总是从所有页面中随机挑一个置换出去,但我们知道页面的访问存在着局部性的原理,并不是随机的,因此它的性能较差。
3、最近最久未使用算法的性能较好相较于先进先出和两种clock算法,最近最久未使用算法的性能略好,我们测试的数据规模相对较小,相信如果采用更大规模的数据,其优势会更加明显。
当从课堂上我们知道要想在实际的应用中实现本算法,用软件的方法速度太慢,影响程序执行效率,如果采用硬件方法实现,则需要增加大量的硬件设备。
4、先进先出与clock算法的性能基本相同这是由于两种clock算法遍历链表采用的就是FIFO的方法,而改进的clock 算法相比于简单clock算法的优势主要体现在会根据是否被修改进行选择,以减少写回所花费的时间。
十、实验总结:这次实验总体难度不是很大,需要实现的算法数目虽然不少,但基本思路较为相似,因此实现起来也并不是十分困难。
通过完成这次实验,除了加深了我对几种策略的理解,锻炼了我的编程能力,另一个巨大的收获就是了解了一些生成测试数据的方法。
为了使我们的测试数据更贴近现实,我们引入了工作集的概念,并根据实际使用情况的特点设计出尽可能符合实际情况的随机数生成方案。
通过阅读课件再加上自己的理解,我了解了老师的设计思路,感觉这个思路极其巧妙,设计中用到的方法和体现出的很多思想值得我们学习。
十一、程序清单:#include<iostream>#include<windows.h>#include<time.h>#include<malloc.h>#include<conio.h>using namespace std;#define ref_size 20#define phy_size 3int ref[ref_size];float interrupt[6]={0.0};//int ref[ref_size]={0};int phy[phy_size];//////////////////////////////////////////////////////////////////void set_rand_num() //产生具有局部特性的随机数列{cout<<"页面访问序列:"<<endl;int p=12;int e=4;int m=4;int i=0;int j=0;int n=0;double t=0.6;int temp;for(i=0;i<m;i++,j++){Sleep(1000*i);srand(time(NULL));temp=rand()%e+p;ref[j]=temp;cout<<ref[j]<<" ";}for(n=0;n<4;n++){Sleep(1000*n);srand(time(NULL));double r=(double)(rand()%10)/10.0;//cout<<r<<endl;if(r<t) p=p+int(10*r);elsep=(p+1)%20;for(i=0;i<m;i++,j++){Sleep(1000*i);srand(time(NULL));temp=rand()%e+p;ref[j]=temp;cout<<ref[j]<<" ";}}cout<<endl;}//////////////////////////////////////////////////////////////// typedef struct QNode //定义队列数据结构{int data;struct QNode *next;}QNode,*QueuePtr;typedef struct{QueuePtr front; //头指针QueuePtr rear; //尾指针}LinkQueue;//定义链表结点typedef struct LNode //定义循环链表数据结构{int data;int flag; //访问位int modify; //修改位struct LNode *next;}LNode,*LinkList;///////////////////////////////////////////////////////////////////// /////对循环链表的一些操作int CreatList(LinkList &L)//创建循环带有头结点的链表{L=(LinkList)malloc(sizeof(LNode));if(!L) exit(-1);L->next=L;L->flag=0;return 1;}int Exchange_LNode(LinkList &L,int e,int i)//将链表L中序号为i的结点替换为内容为e的结点{if(L->next==L) exit(-1);LinkList p,q;int j=0;p=(LinkList)malloc(sizeof(LNode));q=(LinkList)malloc(sizeof(LNode));q->data=e;p=L;for(j=0;j<i;j++)//使p为待更换结点的前一个结点,故应保证,删除第一个非头结点时i=0,以此类推p=p->next;q->next=p->next->next;p->next=q;q->flag=1; //设置新结点的访问位为1q->modify=0; //设置新结点的修改位为0return 1;}int Insert_LNode(LinkList &L,int e)//在循环链表中插入新的结点,从L头结点开始依次向后插入{LinkList p,q;p=(LinkList)malloc(sizeof(LNode));q=(LinkList)malloc(sizeof(LNode));q->data=e;q->flag=1; //设置新结点的访问位为1q->modify=0; //设置新结点的修改位为0p=L;while(p->next!=L)p=p->next;}p->next=q;q->next=L;return 1;}bool Search_LinkList(LinkList &L,int e,int &i)//找到链表L中内容为e 的结点,并用i返回其位置,i=1表示第一个非头结点,依次类推{i=1;if(L->next==L) exit(-1);LinkList p;p=(LinkList)malloc(sizeof(LNode));if(!p) exit(-1);p=L->next; //p指向链表的第一个结点(非头结点)while(p!=L && p->data!=e){p=p->next;i++;}if(p==L) //没有找到符合要求的结点return false;return true;}void Search_LL_Flag(LinkList &L,int &i)//用i返回第一个flag为0的结点的位置,i=1表示第一个非头结点,以此类推{i=1;LinkList p;p=(LinkList)malloc(sizeof(LNode));if(!p) exit(-1);p=L->next;while(p->flag!=0){p->flag=0; //修改访问标志位为0p=p->next;if(p==L) //跳过头结点p=p->next;i++;if(i==4) //跳过头结点i=1;//return 1;}void Set_LL_Flag(LinkList &L,int i) //设置链表L中的序号为i的结点的flag标志为1;{LinkList p;p=(LinkList)malloc(sizeof(LNode));if(!p) exit(-1);p=L->next;if(i==1)p->flag=1;if(i==2){p=p->next;p->flag=1;}if(i==3){p=p->next;p=p->next;p->flag=1;}}int Search_LL_ModifyClock(LinkList &L,int &modify_num)//找到改进的CLOCK算法所需要淘汰的页,用modify_num返回其位置{modify_num=1;if(L->next==L) exit(-1);LinkList p;p=(LinkList)malloc(sizeof(LNode));if(!p) exit(-1);p=L->next; //p指向链表的第一个结点(非头结点)while(p!=L) //第一轮扫描A=0并且M=0的结点{if(p->flag==0 && p->modify==0)break; //找到p=p->next;modify_num++;}if(p==L){modify_num=1;p=L->next;while(p!=L) //第二轮扫描A=0并且M=1的结点,同时修改访问过的结点的访问位为0{if(p->flag!=0)p->flag=0;else if(p->modify==1)break;p=p->next;modify_num++;}}if(p==L){modify_num=1;p=L->next;while(p!=L) //第三轮扫描A=0并且M=0的结点{if(p->flag==0 && p->modify==0)break;p=p->next;modify_num++;}if(p==L){modify_num=1;p=L->next;while(p!=L) //第四轮扫描A=0并且M=1的结点{if(p->flag!=0)p->flag=0;else if(p->modify==1)break;p=p->next;modify_num++;}}}return 1;}void Set_LL_modify(LinkList &L,int i) //设置链表L中的序号为i的结点的modify标志为1;{LinkList p;p=(LinkList)malloc(sizeof(LNode));if(!p) exit(-1);p=L->next;if(i==0)p->modify=1;if(i==1){p=p->next;p->modify=1;}if(i==2){p=p->next;p=p->next;p->modify=1;}}int DestroyLinkList(LinkList &L) //删除链表,并释放链表空间{LinkList p,q;p=(LinkList)malloc(sizeof(LNode));if(!p) exit(-1);q=(LinkList)malloc(sizeof(LNode));if(!q) exit(-1);p=L->next;while(p!=L){q=p->next;free(p);p=q;}free(q);return 1;}////////////////////////////////////////////////////////////////对队列的一些操作int InitQueue(LinkQueue &Q) //队列初始化{Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));if(!Q.front) exit(-1);Q.front->next=NULL;return 1;}int EnQueue(LinkQueue &Q,int e) //插入元素e为Q的新的队尾元素{QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));if(!p) exit(-1);p->data=e;p->next=NULL;Q.rear->next=p;Q.rear=p;return 1;}int DeQueue(LinkQueue &Q,int &e) //若队列不空,则删除Q的队头元素,用e返回其值{if(Q.front==Q.rear) return -1;QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));p=Q.front->next;e=p->data;Q.front->next=p->next;if(Q.rear==p)Q.rear=Q.front;free(p);return 1;}bool SearchQueue(LinkQueue &Q,int e,int &i) //寻找队列Q中结点data 域等于e的结点,并用i返回其在Q中的位置{i=1;if(Q.front==Q.rear) exit(-1);QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));if(!p) exit(-1);p=Q.front->next; //p指向队列的第一个节点(非头结点)while(p!=NULL && p->data!=e){p=p->next;i++;}if(!p)return false;return true;}int DelMid_Queue(LinkQueue &Q,int &e) //删除Q的中间元素,并用e 返回其值{if(Q.front==Q.rear) return -1;QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));if(!p) exit(-1);p=Q.front->next;e=p->next->data;p->next=p->next->next;return 1;}int DestroyQueue(LinkQueue &Q) //删除队列并释放空间{while(Q.front){Q.rear=Q.front->next;free(Q.front);Q.front=Q.rear;}return 1;}//////////////////////////////////////////////////////////////int max1(int a,int b, int c) //返回a,b,c中的最大值{if(a<b) a=b;if(a<c) a=c;return a;}int getnum(int a,int b) //用b返回元素a在被引用数列中的下一个位置{for(;b<ref_size;b++){if(a==ref[b])break;}return b;}void ORA() /////////////最佳置换算法{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_RED);cout<<"\n***********************最佳置换算法*************************"<<endl;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_INTENSITY);//设置字体颜色为白色int i,j;int num_0,num_1,num_2,num_max;int interrupt_num=0;//num_0=num_1=num_2=0;for(i=0;i < phy_size;i++) //前三个数进内存phy[i]=ref[i];for(i=0;i<phy_size;i++) //输出最初的三个数cout<<phy[i]<<"\t";cout<<endl;for(j=phy_size;j<ref_size;j++){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_INTENSITY);if(!(ref[j]==phy[0] || ref[j]==phy[1] || ref[j]==phy[2])) //若产生缺页中断,选择最久不会被使用的页被替换{num_0=getnum(phy[0],j+1);num_1=getnum(phy[1],j+1);num_2=getnum(phy[2],j+1);num_max=max1(num_0,num_1,num_2);if(num_0==num_max)phy[0]=ref[j];elseif(num_1==num_max)phy[1]=ref[j];elseif(num_2==num_max)phy[2]=ref[j];interrupt_num++;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_BLUE);//设置字体为蓝色}cout<<"进入页:"<<ref[j]<<endl;for(i=0;i<phy_size;i++) //输出内存状态cout<<phy[i]<<"\t";cout<<endl<<endl;}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_GREEN);cout<<"最佳置换算法缺页中断次数:"<<interrupt_num<<endl; //以绿色字体输出中断次数interrupt[0]=((float)interrupt_num/20.0)*100.0;}///////////////////////////////////////////////////////////////////// ////////////////////////////////void RAND() /////////////随机置换算法{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_RED);cout<<"\n***********************随机置换算法************************"<<endl;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_INTENSITY);int i,j,temp;int interrupt_num=0;//num_0=num_1=num_2=0;Sleep(1000);srand(time(NULL)); //设置时间种子for(i=0;i < phy_size;i++)phy[i]=ref[i];for(i=0;i<phy_size;i++)cout<<phy[i]<<"\t";cout<<endl;for(j=phy_size;j<ref_size;j++){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_INTENSITY);if(!(ref[j]==phy[0] || ref[j]==phy[1] || ref[j]==phy[2])) //产生缺页中断,随机选择页被替换{temp=rand()%3;//cout<<temp<<endl;phy[temp]=ref[j];interrupt_num++;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_BLUE);}cout<<"进入页:"<<ref[j]<<endl;for(i=0;i<phy_size;i++)cout<<phy[i]<<"\t";cout<<endl<<endl;}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_GREEN);cout<<"随机置换算法缺页中断次数:"<<interrupt_num<<endl; //以绿色字体输出中断次数interrupt[1]=((float)interrupt_num/20.0)*100.0;}///////////////////////////////////////////////////////////////////// //////////////////////////void FIFO(){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_RED);cout<<"\n***********************先进先出置换算法*************************"<<endl;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_INTENSITY);LinkQueue L;QueuePtr p;int i,j,e,m;int interrupt_num=0;InitQueue(L);for(i=0;i<phy_size;i++){EnQueue(L,ref[i]);}p=(QueuePtr)malloc(sizeof(QNode));p=L.front->next;for(j=0;p!=NULL && j<phy_size;j++)//前三个数进内存{cout<<p->data<<"\t";p=p->next;}cout<<endl;for(i=phy_size;i<ref_size;i++){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_INTENSITY);if(!SearchQueue(L,ref[i],m)) //产生缺页中断,选择最先进入的页被替换{DeQueue(L,e);//cout<<e<<endl;EnQueue(L,ref[i]);interrupt_num++;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_BLUE);}cout<<"进入页:"<<ref[i]<<endl;p=L.front->next;for(j=0;p!=NULL && j<phy_size;j++){cout<<p->data<<"\t";p=p->next;}cout<<endl<<endl;}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_GREEN);cout<<"先进先出置换算法缺页中断次数:"<<interrupt_num<<endl;//以绿色字体输出中断次数interrupt[2]=((float)interrupt_num/20.0)*100.0;free(p);DestroyQueue(L);}///////////////////////////////////////////////////////////////////// ///////////////////////////void LRU() /////////最近最久未使用算法{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_RED);cout<<"\n**********************最近最久未使用置换算法**********************"<<endl;int QNode_num=0;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_INTENSITY);LinkQueue L;QueuePtr p;int i,j,e;int interrupt_num=0;InitQueue(L);for(i=0;i<phy_size;i++){EnQueue(L,ref[i]);}p=(QueuePtr)malloc(sizeof(QNode));p=L.front->next;for(j=0;p!=NULL && j<phy_size;j++){cout<<p->data<<"\t";p=p->next;}cout<<endl;for(i=phy_size;i<ref_size;i++){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_INTENSITY);if(!SearchQueue(L,ref[i],QNode_num)) //产生缺页中断,选择最“老”的页面被替换{DeQueue(L,e);//cout<<e<<endl;EnQueue(L,ref[i]);interrupt_num++;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_BLUE);}else if(QNode_num==1) //如果接下来是内存中的第一个,则将它移到最后一个,即标志为最近使用的页{EnQueue(L,ref[i]);DeQueue(L,e);}else if(QNode_num==2) //如果接下来是内存中的第二个,则将它删除,并在队列尾部添加相同元素,即标志为最近使用的页{DelMid_Queue(L,e);EnQueue(L,e);}cout<<"进入页:"<<ref[i]<<endl;p=L.front->next;for(j=0;p!=NULL && j<phy_size;j++) //输出内存状况{cout<<p->data<<"\t";p=p->next;}cout<<endl<<endl;}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_GREEN);cout<<"最近最久未使用置换算法缺页中断次数:"<<interrupt_num<<endl;//以绿色字体输出中断次数interrupt[3]=((float)interrupt_num/20.0)*100.0;DestroyQueue(L);free(p);}///////////////////////////////////////////////////////////////////// ////////////////////////////////void CLOCK(){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_RED);cout<<"\n***********************CLOCK置换算法*************************"<<endl;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_INTENSITY);int interrupt_num=0;int i;int LNode_hit_num=0; //标记带内存中与带进入页面相同的页面的位置int LNode_flag_num=0; //标记访问位为0的页面在内存中的位置LinkList L;CreatList(L);LinkList p;p=(LinkList)malloc(sizeof(LNode));for(i=0;i<phy_size;i++){Insert_LNode(L,ref[i]);}if(L->next==L) exit(-1);p=L->next;for(;p!=L;p=p->next){cout<<p->data<<"\t";//p->flag=1;}cout<<endl;p=L->next;while(p!=L){cout<<"A:"<<p->flag<<"\t";p=p->next;}cout<<endl<<endl;for(i=phy_size;i<ref_size;i++){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_INTENSITY);if(!Search_LinkList(L,ref[i],LNode_hit_num)){Search_LL_Flag(L,LNode_flag_num);//找到第一个flag标志为0的结点,其序号记录在LNode_flag_num中LNode_flag_num--;Exchange_LNode(L,ref[i],LNode_flag_num);//将链表L中序号为LNode_flag_num的结点替换为内容为ref[i]的结点interrupt_num++;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_BLUE);}elseSet_LL_Flag(L,LNode_hit_num);cout<<"进入页:"<<ref[i]<<endl;p=L->next;for(;p!=L;p=p->next){cout<<p->data<<"\t";//p->flag=1;}cout<<endl;p=L->next;while(p!=L){cout<<"A:"<<p->flag<<"\t";p=p->next;}cout<<endl<<endl;}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_GREEN);cout<<"CLOCK置换算法缺页中断次数:"<<interrupt_num<<endl; //以绿色字体输出中断次数interrupt[4]=((float)interrupt_num/20.0)*100.0;DestroyLinkList(L);//free(L);}///////////////////////////////////////////////////////////////////// ///////////////////////////void Modified_Clock(){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_RED);cout<<"\n*******************改进的CLOCK置换算法*************************"<<endl;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_INTENSITY);int interrupt_num=0;int i,temp;int LNode_hit_num=0;int LNode_flag_num=0;int LNode_modify_num=0;LinkList L;CreatList(L);LinkList p;p=(LinkList)malloc(sizeof(LNode));for(i=0;i<phy_size;i++){Insert_LNode(L,ref[i]);}if(L->next==L) exit(-1);p=L->next;for(;p!=L;p=p->next){cout<<p->data<<"\t\t";//p->flag=1;}cout<<endl;Sleep(1000);srand(time(NULL)); //设置时间种子temp=rand()%3;cout<<"修改页(内存中序号):"<<temp<<endl;Set_LL_modify(L,temp);p=L->next;while(p!=L){cout<<"A:"<<p->flag<<"\tM:"<<p->modify<<"\t";p=p->next;}cout<<endl<<endl;for(i=phy_size;i<ref_size;i++){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_INTENSITY);if(!Search_LinkList(L,ref[i],LNode_hit_num)){Search_LL_ModifyClock(L,LNode_modify_num);//Search_LL_Flag(L,LNode_flag_num);LNode_modify_num--;Exchange_LNode(L,ref[i],LNode_modify_num);interrupt_num++;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_BLUE);}elseSet_LL_Flag(L,LNode_hit_num);//SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGRO UND_INTENSITY | FOREGROUND_INTENSITY);cout<<"进入页:"<<ref[i]<<endl;p=L->next;for(;p!=L;p=p->next){cout<<p->data<<"\t\t";//p->flag=1;}cout<<endl;Sleep(1000);srand(time(NULL)); //设置时间种子temp=rand()%3;cout<<"修改页(内存中序号):"<<temp<<endl;Set_LL_modify(L,temp);p=L->next;while(p!=L){cout<<"A:"<<p->flag<<"\tM:"<<p->modify<<"\t";p=p->next;}cout<<endl<<endl;}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_GREEN);cout<<"改进的CLOCK置换算法缺页中断次数:"<<interrupt_num<<endl;//以绿色字体输出中断次数interrupt[5]=((float)interrupt_num/20.0)*100.0;DestroyLinkList(L);//free(L);}///////////////////////////////////////////////////////////////////// //////////////////////////int main(){cout<<"\n\n"<<endl;cout<<"************************页面置换算法*****************************\n"<<endl;cout<<"******北京交通大学--计科1104(进修生)--房皓--13410801***********\n\n"<<endl;set_rand_num();ORA();RAND();FIFO();LRU();CLOCK();Modified_Clock();//*/SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_GREEN);cout<<"\n\n\t\t总结:"<<endl;cout<<"\n\t\t\t缺页率"<<endl;cout<<"\n最佳置换\t\t"<<interrupt[0]<<"%"<<endl;cout<<"\n随机置换\t\t"<<interrupt[1]<<"%"<<endl;cout<<"\n先进先出置换\t\t"<<interrupt[2]<<"%"<<endl;cout<<"\n最近最久未使用置换\t"<<interrupt[3]<<"%"<<endl;cout<<"\nCLOCK置换\t\t"<<interrupt[4]<<"%"<<endl;cout<<"\n改进CLOCK置换\t\t"<<interrupt[5]<<"%"<<endl;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN D_INTENSITY | FOREGROUND_INTENSITY);return 1;}。