操作系统实验页面置换算法C++代码
页面置换算法模拟实验报告
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算法
【精品】页面置换算法实验报告
【精品】页面置换算法实验报告一、实验目的了解操作系统中的页面置换算法,并实现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算法的实现需要维护一个记录页面使用时间的链表或队列。
操作系统实验参考代码
目录实验一WINDOWS进程初识 (2)实验二进程管理 (6)实验三进程同步的经典算法 (10)实验四存储管理 (14)试验五文件系统试验 (18)实验有关(参考)代码实验一WINDOWS进程初识1、实验目的(1)学会使用VC编写基本的Win32 Consol Application(控制台应用程序)。
(2)掌握WINDOWS API的使用方法。
(3)编写测试程序,理解用户态运行和核心态运行。
2、程序清单清单1-1 一个简单的Windows控制台应用程序// hello项目# include <iostream>void main(){std::cout << “Hello, Win32 Consol Application” << std :: endl ;}清单1-2 核心态运行和用户态运行时间比计算// proclist项目# include <windows.h># include <tlhelp32.h># include <iostream.h>// 当在用户模式机内核模式下都提供所耗时间时,在内核模式下进行所耗时间的64位计算的帮助方法DWORD GetKernelModePercentage(const FILETIME& ftKernel,const FILETIME& ftUser){// 将FILETIME结构转化为64位整数ULONGLONG qwKernel=(((ULONGLONG)ftKernel.dwHighDateTime)<<32)+ftKernel.dwLowDateTime;ULONGLONG qwUser=(((ULONGLONG)ftUser.dwHighDateTime)<<32)+ftUser.dwLowDateTime;// 将消耗时间相加,然后计算消耗在内核模式下的时间百分比ULONGLONG qwTotal=qwKernel+qwUser;DWORD dwPct=(DWORD)(((ULONGLONG)100*qwKernel)/qwTotal);return(dwPct);}// 以下是将当前运行过程名和消耗在内核模式下的时间百分数都显示出来的应用程序void main(int argc,char *argv[]){if(argc<2){cout<<"请给出你要查询的程序名"<<endl;exit(0);}// 对当前系统中运行的过程拍取“快照”HANDLE hSnapshot=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,// 提取当前过程0);// 如果是当前过程,就将其忽略// 初始化过程入口PROCESSENTRY32 pe;::ZeroMemory(&pe,sizeof(pe));pe.dwSize=sizeof(pe);BOOL bMore=::Process32First(hSnapshot,&pe);BOOL found = FALSE;while(bMore){// 打开用于读取的过程if(!strcmp(pe.szExeFile,argv[1])){found = TRUE;HANDLE hProcess=::OpenProcess(PROCESS_QUERY_INFORMA TION,// 指明要得到信息FALSE,// 不必继承这一句柄pe.th32ProcessID);// 要打开的进程if (hProcess!=NULL){// 找出进程的时间FILETIME ftCreation,ftKernelMode,ftUserMode,ftExit;::GetProcessTimes(hProcess,// 所感兴趣的进程&ftCreation,// 进程的启动时间&ftExit,// 结束时间(如果有的话)&ftKernelMode,// 在内核模式下消耗的时间&ftUserMode);// 在用户模式下消耗的时间// 计算内核模式消耗的时间百分比DWORD dwPctKernel=::GetKernelModePercentage(ftKernelMode,// 在内核模式上消耗的时间ftUserMode);// 在用户模式下消耗的时间// 向用户显示进程的某些信息cout<< "process ID: " << pe.th32ProcessID<< ",EXE file:" << pe.szExeFile<< ",%d in Kernel mode: " << dwPctKernel << endl;// 消除句柄::CloseHandle(hProcess);}}// 转向下一个进程bMore=::Process32Next(hSnapshot,&pe);}if(found==FALSE){cout<<"当前系统没有这个可执行程序正在运行"<<endl;exit(0);}}清单1-3 核心态运行和用户态运行时间测试程序#include <stdio.h>main(){int i,j;while(1){for(i=0;i<1000;i++);for(j=1;j<1000;j++) printf(“enter kernel mode running.”);}}实验二进程管理1、实验目的1) 通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解Windows进程的“一生”。
页面置换算法实验源代码
#include <stdio.h>#include <stdlib.h>#include <time.h>#include <malloc.h>#define M 4 //物理页数#define N 20 //需要调入的页数#define LEN sizeof(struct node)/** @auther by 12281201 sunyangwei*/typedef struct page{int num;int time;}Page; //物理页项,包括调入的页号和时间struct node //定义空闲链表数据结构{int num;struct node *next;};Page mm[M]; //3个物理页int K=0,S=0,T=0,Q=0; //记录缺页率int pos=0;//记录存在最长时间项//初始化内存页表项及存储内存情况的空间void INIT(){int i;for(i=0;i<M;i++){mm[i].num =-1;mm[i].time =0;}}//建立链表struct node* create(){struct node *head;head = (struct node*)malloc(LEN);head->next = NULL;return (head);}//打印链表void print(struct node * head)struct node * p;printf("Now,链表页面:");p=head->next;if(p==NULL){printf("链表为空\n");}else {do{printf("%3d",p->num);p=p->next;}while(p!=NULL);}printf("\n");}//链表插入结点(页)struct node* insert(struct node* head,struct node * newnode){struct node *p1;p1=head->next;if(p1==NULL)//原来的链表是空表,新的节点直接插到头结点后面{head->next=newnode;newnode->next = NULL;}else//如果不是空表,则遍历寻找合适的插入位置{while((p1->next!=NULL)){p1=p1->next;//后移}p1->next = newnode;newnode->next = NULL;}return(head);}//删除结点struct node* delete(struct node* head,int num){struct node *p1,*p2;p1=head->next;p2 = head;while(p1!=NULL&&num!=p1->num){p2=p1;p1=p1->next;}if(p1!=NULL&&num==p1->num){p2->next=p1->next;}return (head);}//取得内存中存在时间最久的位置int GetMax(){int max=-1;int i;for(i=0;i<M;i++){if(mm[i].time > max){max=mm[i].time ;pos=i;}}return pos;}//检查最长时间不使用页面int longesttime(int i,int array[]){int max=-1;mm[0].time=0;mm[1].time=0;mm[2].time=0;for(int q=0;q<M;q++){for(int count=i;count<N;count++){if(mm[q].num==array[count]){mm[q].time=count;break;}}}for(int iii=0;iii<M;iii++){if(mm[iii].time==0){pos = iii;break;}else if((mm[iii].time!=0) && (mm[iii].time>max) ){max=mm[iii].time;pos=iii;}}return pos;}int getPrePos(int i,int array[])//得到最久没有使用的页面位置{int min=20;mm[0].time=0;mm[1].time=0;mm[2].time=0;for(int r=0;r<M;r++){for(int p=i;p>=0;p--){if(mm[r].num == array[p]){mm[r].time = p;break;}}}for(int j=0;j<M;j++){if(mm[j].time<min){min = mm[j].time;pos=j;}}return pos;}int is_intable(int pagenum,struct node * head){struct node *temp;temp=head->next;/*取得链表的头指针*/while(temp!=NULL)/*只要是非空表*/{if(pagenum ==temp->num){return 1;}temp=temp->next;/*跟踪链表增长*/}return 0;}//检查某页是否在内存,不存在返回-1,存在返回物理块编号int Equation(int fold){int i;for(i=0;i<M;i++){if(mm[i].num == fold)return i;}return -1;}//检查物理内存是否已满,-1表满,其他不满int Check(){int i;for(i=0;i<M;i++){if(mm[i].num == -1)return i;}return -1;}//先进先出void FIFO(int fold){int i;int a,b,c;a=Equation(fold);//a代表物理块编号//页已存在if(a != -1){}//页不存在b=Check();//内存还有空闲if(b != -1){mm[b].num = fold;}//内存已满,需要置换else {c=GetMax();mm[c].num = fold;mm[c].time = 0;K++;}}printf("访问页面%d",fold);for(int j=0;j<M;j++){printf("%3d",mm[j].num);}printf("\n");for(i=0;i<M;i++){if(mm[i].num != -1){mm[i].time ++;}}}void OPT(int i,int array[]){int a,b,c;a=Equation(array[i]);if(a == -1){//页不在内存b=Check();//内存还有空闲if(b != -1){mm[b].num = array[i];}//内存已满,需要置换else{c=longesttime(i,array);mm[c].num = array[i];T++;}printf("访问页面%d",array[i]);for(int j=0;j<M;j++){printf("%3d",mm[j].num);}printf("\n");}void LRU(int i,int array[]){int a,b,c;a = Equation(array[i]);if(a == -1){//页不在内存b=Check();//内存还有空闲if(b != -1){mm[b].num = array[i];}//内存已满,需要置换else{c=getPrePos(i,array);mm[c].num = array[i];S++;}}printf("访问页面%d",array[i]);for(int j=0;j<M;j++){printf("%3d",mm[j].num);}printf("\n");}void PBA(int i,int array[],struct node * head)//与fifo算法类似,只是置换下来的页面存放在链表里面{int a,c;struct node * newnode;if(Equation(array[i]) !=-1){}//页已在内存else {//页不在内存a=Check();if(a != -1){//检查内存是否有空闲,有空闲,则不需要调换mm[a].num = array[i];}else{//内存没有空闲,需要置换页面//页面在链表里面if(is_intable(array[i],head)==1) {//页面在链表里面c=GetMax();//得到物理块中要被置换出来的页面//从链表里删除节点(页面)head = delete(head,array[i]);//在表尾插入置换下来的节点(页面)newnode=(struct node*)malloc(LEN);newnode->num= mm[c].num;head = insert(head,newnode);mm[c].num =array[i];mm[c].time = 0;}else{//不在链表里面c=GetMax();newnode=(struct node*)malloc(LEN);newnode->num= mm[c].num;head = insert(head,newnode);mm[c].num = array[i];mm[c].time = 0;Q++;printf("Q:%d\n",Q);print(head);}}}printf("访问页面%d",array[i]);for(int j=0;j<M;j++){printf("%3d",mm[j].num);}printf("\n");for(int p=0;p<M;p++){if(mm[p].num != -1){mm[p].time ++;}}}/*符合局部访问特性的随机生成算法确定虚拟内存的尺寸pageNum,工作集的起始位置p,工作集中包含的页数e,工作集移动率m(每处理m个页面访问则将起始位置p +1),以及一个范围在0和1之间的值t;生成m个取值范围在p和p + e间的随机数,并记录到页面访问序列串中;生成一个随机数r,0 ≤r ≤1;如果r < t,则为p生成一个新值,否则p = (p + 1) mod N;如果想继续加大页面访问序列串的长度,请返回第2步,否则结束。
页面置换算法实验(内含完整代码)
实验二存储管理一、实验目的通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。
二、实验内容基于一个虚拟存储区和内存工作区,设计下述算法并计算访问命中率。
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.程序的执行结果如下:(1)先进先出页面置换算法(2)最佳页面置换法(3)最近最久未使用置换算法2.以上三个程序通过数组和排序语句实现页面的三种基本调度算法。
(1)先进先出算法事先设定标志k=3,页面每发生一次置换k值增加1。
通过取k对3的余数来确定被置换的内存中的页面,当被访问页面存在于内存时,不置换,而直接输出原内存中的3个页面。
(2)最佳置换算法通过设定c1,c2,c3来记录当前内存中的页面被下一次访问的位置(时间),通过对c1,c2,c3的大小比较确定内存中需要被置换的页面。
三者中值最大的对应的内存页面选择被置换。
即实现了未来最长时间未访问的机制,即最佳置换算法。
(3)最近最久未使用置换算法的原理跟最佳置换算法类似。
初始设定变量c1,c2,c3记录当前内存中的以前的最近一次未被访问的位置(时间),比较三者的大小来确定需要被置换的页面。
三者中至最小的对应的内存页面选择被置换。
即实现了最近最久未使用的机制,即最近最久未使用置换算法。
3.上述三个程序分别能较好的模拟页面的基本调度算法,实现页面的置换,保证进程的正常执行。
但也分别存在一些不足。
(1)当内存中三个页面有部分相同时,程序不能很好的实现调度。
即c1,c2,c3中有部分变量值相等,源程序可能不能准确的找到调度顺序,如图所示。
(LRU算法)改进的方法为在c1,c2,c3间的大小比较判断语句中增加关系语句的默认处理办法,当三者间有部分相同时,默认选择按从前到后的顺序执行。
比如当c2=c3的时候选择页面a[2]进行置换。
当c1=c2=c3时则选择页面a[0]进行置换。
也就相当于无法运用LRU算法调用的时候折衷采取先进先出置换算法,以实现页面的合理调度,提高页面的利用效率。
指导教师签名:20 年月日【备注】。
页面置换算法实验报告
页面置换算法实验报告一、实验目的本次实验的目的是通过模拟页面置换算法的过程,了解不同算法的优缺点,掌握算法的实现方法,以及对算法的性能进行评估。
二、实验原理页面置换算法是操作系统中的一个重要概念,它是为了解决内存不足的问题而产生的。
当系统中的进程需要使用内存时,如果内存已经被占满,就需要将一些页面从内存中置换出去,以便为新的页面腾出空间。
页面置换算法就是用来决定哪些页面应该被置换出去的算法。
常见的页面置换算法有以下几种:1. 最佳置换算法(OPT)最佳置换算法是一种理论上的最优算法,它总是选择最长时间内不会被访问的页面进行置换。
但是,由于无法预测未来的页面访问情况,因此最佳置换算法无法在实际中使用。
2. 先进先出置换算法(FIFO)先进先出置换算法是一种简单的置换算法,它总是选择最先进入内存的页面进行置换。
但是,这种算法容易出现“抖动”现象,即频繁地将页面置换出去,然后再将其置换回来。
3. 最近最久未使用置换算法(LRU)最近最久未使用置换算法是一种比较常用的置换算法,它总是选择最长时间未被访问的页面进行置换。
这种算法可以避免“抖动”现象,但是实现起来比较复杂。
4. 时钟置换算法(Clock)时钟置换算法是一种改进的FIFO算法,它通过维护一个环形链表来实现页面置换。
当需要置换页面时,算法会从当前位置开始扫描链表,如果找到一个未被访问的页面,则将其置换出去。
如果扫描一圈后都没有找到未被访问的页面,则将当前位置的页面置换出去。
三、实验过程本次实验使用Python语言编写了一个页面置换算法模拟程序,可以模拟上述四种算法的过程,并输出算法的性能指标。
程序的主要流程如下:1. 读取输入文件,获取页面访问序列和内存大小等参数。
2. 根据选择的算法,初始化相应的数据结构。
3. 遍历页面访问序列,模拟页面置换的过程。
4. 输出算法的性能指标,包括缺页率、页面置换次数等。
下面分别介绍四种算法的实现方法。
1. 最佳置换算法(OPT)最佳置换算法需要预测未来的页面访问情况,因此需要遍历整个页面访问序列,找到最长时间内不会被访问的页面。
页面置换算法模拟实现
页面置换算法模拟实现学院专业学号学生姓名指导教师姓名2014年3月 19日一.课程设计的目的:操作系统课程设计是计算机专业重要的教学环节,它为学生提供了一个既动手又动脑,将课本上的理论知识和实际有机的结合起来,独立分析和解决实际问题的机会。
l 进一步巩固和复习操作系统的基础知识。
l 培养学生结构化程序、模块化程序设计的方法和能力。
l 提高学生调试程序的技巧和软件设计的能力。
l 提高学生分析问题、解决问题以及综合利用C 语言进行程序设计的能力。
二.设计内容:根据设计要求实现对页面置换算法的模拟三 .设计要求:设计一个虚拟存储区和内存工作区,编程序演示下述算法的具体实现过程,并计算访问命中率。
用C 语言实现,要求设计主界面以灵活选择某算法,且以下算法都要实现1、先进先出算法(FIFO);2、最近最久未使用算法(LRU)3、最佳置换算法(OPT)四、程序流程图1、主函数2、FIFO3、LRU五、系统测试程序进行实例如下:1.开始界面,按任意键继续:2.算法结果:运行界面:(1)FIFO算法结果:(2)OPT算法结果:(3)LRU算法结果六. 源程序及系统文件使用说明#include< iostream.h >#include"stdlib.h"typedef int QElemType;#define ok 1#define overflow 0#define error 0typedef struct Qnode { QElemType data;struct Qnode *next;}Qnode,*Queueptr;typedef struct {Queueptr front;Queueptr rear;}LinkQueue;InitQueue( LinkQueue &Q ) {Q.front = Q.rear = ( Queueptr )malloc( sizeof( Qnode )); if( !Q.front ) exit ( overflow );Q.front->next =NULL;return ok;}EnQueue( LinkQueue &Q,QElemType e ) {Queueptr p;p = ( Queueptr )malloc( sizeof( Qnode ));if( !p ) exit( overflow );p->data = e;p->next = NULL;Q.rear->next = p;Q.rear = p;return ok;}DeQueue( LinkQueue &Q,QElemType &e ) {Queueptr p;if( Q.front == Q.rear ) return error;p = Q.front->next;e = p->data;Q.front->next = p->next;if( Q.rear == p ) Q.rear = Q.front;free( p );return ok;}void VisitQueue( LinkQueue Q ) {Queueptr p;p = Q.front->next;while( p ) { cout << p->data << " ";p = p->next; } }CompareQueue( LinkQueue Q,int page ) {Queueptr p;p = Q.front->next;while( p ) {if( p->data == page ) return ok;p = p->next;}return error;}void FIFO( int *a,int n,int m ) {LinkQueue Q;int page, t = 0,flag = 0,x;InitQueue( Q );for( int i = 1;i <= m;i++ ){page = a[ i ];t++;if( t <= n ) { EnQueue( Q,page );cout << a[ i ] << " "; }else {for( int j = 1;j <= n;j++ )if( CompareQueue( Q,page ) ) { t--;flag = 1;break; }if( flag == 0 ) { DeQueue( Q,x );cout << x << " was taken out "<< page << " was taken in";EnQueue( Q,page );}cout << endl;VisitQueue( Q );cout << ":";}flag = 0;}cout << "缺页中断数为:" << endl;cout << "t= " << t << endl;}void LRU( int *a,int n,int m ) {LinkQueue Q;int page, t = 0,flag = 0,x,e;InitQueue( Q );for( int i = 1;i <= m;i++ ){page = a[ i ];t++;if( t <= n ) { EnQueue( Q,page );cout << a[ i ] << " "; } else { for( int j = 1;j <= n;j++ )if( CompareQueue( Q,page ) ) { t--;DeQueue(Q,e);EnQueue(Q,e);flag = 1;break; }if( flag == 0 ) { DeQueue( Q,x );cout << x << " was taken out " << page << " was taken in";EnQueue( Q,page );}cout << endl;VisitQueue( Q );cout << ":";}flag = 0;}cout << "缺页中断数为:" << endl;cout << "t= " << t << endl;}int max( int *t,int n ){int max =t[ 1 ],s = 1;for( int i = 1;i <= n;i++ )if( t[ i ] > max ) {max = t[ i ];s = i;} return s;}void OPT( int a[ 21 ],int n,int m ) {int w = 0,flag = 0;int *t =new int[ n + 1 ];for( int i = 1;i <= m;i++ ){w++;if( w <= n ) cout << a[ i ] << " " ;else{for( int q = 1;q <= n;q++ )if( a[ i ] == a[ q ] ) { w--;flag = 1;break; }if( flag == 0 ){for( int j = 1;j <= n;j++ )for( int k = i;k <= m;k++ ){if( a[ j ] != a[ k ] ) t[ j ]++;else break;}cout << a[ max( t,n ) ] << " " << "was taken out" << " " << a[ i ] << " was taken in ";a[ max( t,n ) ] = a[ i ];}cout << endl;for( int s = 1;s <= n;s++ )cout << a[ s ] << " ";cout << ":";}for( int r = 1;r <= n;r++ ) t[ r ] = 0; flag = 0;}cout << "缺页中断数为:" << endl;cout << "w = " << w << endl;delete [] a;}main(){int m,n;cout << "输入页面数:" << endl;cin >> m;int *a = new int[ m + 1 ];cout << "输入驻留集大小:" << endl;cin >> n;cout << "input the pages" << endl;for( int i = 1;i <= m;i++ )cin >> a[ i ];cout << endl;cout << "The result of FIFO:" << endl;FIFO( a,n,m );cout << endl;cout << "The result of LRU:" << endl;LRU( a,n,m );cout << endl;cout << "The result of OPT:" << endl;OPT( a,n,m );cout << endl;return 0;delete [] a;}七.结论此次C语言程序设计,我收获颇多,不仅巩固了书本上的知识,尤其是数据结构相关的知识点的回顾,例如指针链队列,头指针尾指针,以及队列结点的删除和添加等等。
页面置换算法实验报告
操作系统课程设计报告课程名称:操作系统课程设计课程设计题目:页面置换算法学院:计算机科学与技术学院专业:科技小组成员: 庞思慧E01114081王蒙E01114161姚慧乔E01114349朱潮潮E01114408指导老师:***目录1 实验目的 (3)2 实验要求 (3)3 实验内容与步骤 (3)4 算法思想 (4)5 模块设计 (4)6 程序设计 (5)7 测试结果 (7)8 结果分析 (9)9 程序代码 (9)10 课程设计小结 (24)页面置换算法模拟设计1.实验目的(1)通过模拟实现几种基本页面置换的算法,了解虚拟存储技术的特点。
(2)掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想,并至少用三种算法来模拟实现。
(3)通过对几种置换算法命中率的比较,来对比他们的优缺点。
2.实验要求计算并输出下述各种算法在不同内存容量下的命中率。
A 先进先出的算法(FIFO)B 最近最少使用算法(LRU)C最佳淘汰算法(OPT)3.实验内容与步骤(1)通过随机数产生一个指令序列,共320条指令,具体的实施方法是:A.[0,319]的指令地址之间随机选取一起点M;B.顺序执行一条指令,即执行地址为M+1的指令;C.在前地址[0,M+1]中随机选取一条指令并执行,该指令的地址为M’;D.顺序执行一条指令,其地址为M’+1;E.在后地址[M’+2,319]中随机选取一条指令并执行;F.重复A—E,直到执行320次指令。
(2)指令序列变换成页地址流A.页面大小为1K;B.用户内存容量为4页到32页;C.用户虚存容量为32K。
在用户虚存中,按每K存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为:第0条—第9条指令为第0页(对应虚存地址为[0,9]);第10条—第19条指令为第1页(对应虚存地址为[10,19]);。
第310条—第319条指令为第31页(对应虚存地址为[310,319]);(3)计算并输出上述各种算法在不同内存容量下的命中率。
lru页面置换算法实验c语言总结
LRU页面置换算法实验C语言总结1.引言在计算机科学中,页面置换算法是解决主存容量有限的情况下,如何有效地管理页面(或称为内存块)的一种重要方法。
L RU(L ea st Re ce nt ly Us e d)页面置换算法是其中一种经典的策略,通过淘汰最久未使用的页面来提高内存的利用率。
本文将总结使用C语言实现L RU页面置换算法的相关实验。
2.算法原理L R U页面置换算法的核心思想是:最近被访问的页面可能在未来继续被访问,而最久未被使用的页面可能在未来也不再被访问。
基于这一思想,L R U算法维护一个页面访问的时间顺序链表,每次发生页面置换时,选择链表头部(即最久未使用)的页面进行淘汰。
3.实验设计本次实验旨在使用C语言实现LR U页面置换算法,并通过模拟页面访问的过程来验证算法的正确性。
具体设计如下:3.1数据结构为了实现LR U算法,我们需要定义几个关键的数据结构:3.1.1页面节点结构t y pe de fs tr uc tP age{i n tp ag eI D;//页面I Ds t ru ct Pa ge*n ex t;//下一个节点指针s t ru ct Pa ge*p re v;//上一个节点指针}P ag e;3.1.2内存块结构t y pe de fs tr uc tM emo r y{i n tc ap ac it y;//内存块容量i n ts iz e;//当前存储的页面数量P a ge*h ea d;//内存块链表头指针P a ge*t ai l;//内存块链表尾指针}M em or y;3.2实验步骤本次实验主要包括以下几个步骤:3.2.1初始化内存块根据实际需求,设置内存块的容量,并初始化链表头指针和尾指针。
3.2.2页面置换每次发生页面访问时,检查访问的页面是否已经在内存块中。
如果在,将该页面移动到链表尾部;如果不在,执行页面置换。
3.2.3页面淘汰当内存块已满时,选择链表头部的页面进行淘汰,将新访问的页面加入链表尾部。
页面置换 操作系统实验报告
实验二页面置换算法实现一、实验目的(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之间。
页面置换算法(FIFO算法,LRU算法)
实验四页面置换算法一、实验流程图二、实验程序#include <stdio.h>#include <stdlib.h>#include <malloc.h>#define null 0#define len sizeof(struct page)struct page{ int num;int tag;struct page *next;};struct page *create(int n) /*建立分配的内存空间,并初始化,返回头结点*/{int count=1;struct page *p1,*p2,*head;head=p2=p1=(struct page *)malloc(len); //开辟一个新的单元,并将malloc返回的指针转换为结构体类型的指针p1->tag=-1;p1->num=-1;while(count<n){count++;p1=(struct page *)malloc(len);p1->tag=-1;p1->num=-1;p2->next=p1;p2=p1;}p2->next=null;return(head);}void FIFO(int array[],int n){int *p;struct page *cp,*dp,*head,*new1;int count=0;head=create(n);p=array;while(*p!=-1){ cp=dp=head;for(;cp->num!=*p&&cp->next!=null;) cp=cp->next;if (cp->num==*p) printf(" ! " );else{ count++;cp=head;for(;cp->tag!=-1&&cp->next!=null;) cp=cp->next;if(cp->tag==-1){cp->num=*p;printf(" * ");}else{new1=(struct page*)malloc(len);new1->num=*p;new1->tag=0;new1->next=null;cp->next=new1;head=head->next;printf(" %d ",dp->num);free(dp);}}p++;}printf("\nQueye Zongshu : %d \n",count);}void LRU(int array[],int n){int count=0,*p=array;struct page *head,*cp,*dp,*rp,*new1,*endp;head=create(n);while(*p!=-1){cp=dp=rp=endp=head;for(;endp->next!=null;) endp=endp->next;for(;cp->num!=*p&&cp->next!=null;){rp=cp;cp=cp->next;}if(cp->num==*p){printf(" ! ");if(cp->next!=null){if(cp!=head)rp->next=cp->next;else head=head->next;}endp->next=cp;cp->next=null;}else{count++;cp=rp=head;for(;cp->tag!=-1&&cp->next!=null;) cp=cp->next;{printf(" * ");cp->num=*p;cp->tag=0;}else{new1=(struct page *)malloc(len);new1->num=*p;new1->tag=0;new1->next=null;cp->next=new1;dp=head;head=head->next;printf(" %d ",dp->num);free(dp);}}p++;}printf("\nQueye Zongshu : %d \n",count);}OPT(int array[],int n){int *p,*q,count=0,i;struct page *head,*cp,*dp,*new1;p=array;head=create(n);while(*p!=-1){ cp=head;for(;cp->num!=*p&&cp->next!=null;) cp=cp->next;if(cp->num!=*p){ count++;cp=head;for(;cp->tag!=-1&&cp->next!=null;) cp=cp->next;if(cp->tag==-1){printf(" * ");cp->num=*p;cp->tag=0;}else{ i=1;q=p;q++;cp=head;while(*q!=-1&&i<n){ for(;*q!=cp->num&&cp->next!=null;) cp=cp->next;if(*q==cp->num){cp->tag=1;i++;}q++;cp=head;}if(i==n){for(;cp->tag!=0;) cp=cp->next;printf(" %d ",cp->num);cp->num=*p;}else{ cp=head;for(;cp->tag!=0;) cp=cp->next;if(cp==head){ for(;cp->next!=null;) cp=cp->next;new1=(struct page *)malloc(len);new1->num=*p;new1->tag=0;new1->next=null;cp->next=new1;dp=head;head=head->next;printf(" %d ",dp->num);free(dp);}else{ printf(" %d ",cp->num);cp->num=*p;}}cp=head;for(;cp->next!=null;) {cp->tag=0;cp=cp->next;}cp->tag=0;}}else printf(" ! ");p++;}printf("\nQueye Zongshu : %d \n",count);}main(){FILE *fp;char pt;char str[10];int i,j=0;int page[50],space=0;for(i=0;i<50;i++)page[i]=-1;fp=fopen("page.txt","r+");if(fp==NULL){printf("Cann't open the file\n");exit(0);}i=0;while((pt=fgetc(fp))!=EOF)/*将数字字符串转化成整型-开始*/ {if(pt>='0'&&pt<='9'){str[i]=pt;i++;space=0;}else{if(pt==' '||pt=='\n'){if(space==1) break;else{str[i]='\0';page[j]=atoi(str);if(pt=='\n') break;else{space=1;j++;i=0;}}}}}/*结束*/if(pt==EOF) {str[i]='\0';page[j]=atoi(str);}i=0;while(page[i]!=-1) {printf(" %d ",page[i]);i++;}fclose(fp);printf("\n");printf(" ! : mean no moved \n * : mean have free space \n\n"); printf("FIFO ");FIFO(page,3);printf("\nLRU ");LRU(page,3);printf("\nOPT ");OPT(page,3);}。
【操作系统】页面置换算法(最佳置换算法)(C语言实现)
【操作系统】页⾯置换算法(最佳置换算法)(C语⾔实现)【操作系统】页⾯置换算法(最佳置换算法)(C语⾔实现)(编码⽔平较菜,写博客也只是为了个⼈知识的总结和督促⾃⼰学习,如果有错误,希望可以指出)1.页⾯置换算法:在地址映射过程中,若在页⾯中发现所要访问的页⾯不在内存中,则产⽣缺页中断。
当发⽣缺页中断时,如果操作系统内存中没有空闲页⾯,则操作系统必须在内存选择⼀个页⾯将其移出内存,以便为即将调⼊的页⾯让出空间。
⽽⽤来选择淘汰哪⼀页的规则叫做页⾯置换算法。
⼀个好的页⾯置换算法,应具有较低的页⾯更换频率。
从理论上讲,应该保留最近重复访问的页⾯,将以后都不再访问或者很长时间内不再访问的页⾯调出。
----百度百科2.具体的页⾯置换算法:2.1 最佳置换算法:⼀个进程在内存的若⼲个页⾯中,哪⼀个页⾯是未来最长时间内不再被访问的,那么如果发⽣缺页中断时,就将该页⾯换出,以便存放后⾯调⼊内存中的页⾯。
1.这是计算机操作系统(第四版)中的⼀个例⼦。
系统⾸先为进程分配了三个物理块。
上⾯⼀排数字是作业号。
在转满三个物理块后,要访问2号作业,2号作业不在内存,所以会发⽣缺页中断,然后系统需要将2号作业调⼊内存,但是此时物理块已经装满。
2.依据最佳置换算法,会将7号页换出(0号页在2号页后第1个就会被访问,1号页在2号页后第10个会被访问,7号页在2号页后第14个会被访问,7号页在已经装⼊内存的作业中是未来最长时间不会被访问的,所以换出7号页)。
3.后⾯依次类推。
2.2 先进先出算法:如果发⽣缺页中断,需要换出⼀个页⾯的时候,总是选择最早进⼊内存的页⾯,即选择在内存中驻留时间最久的页⾯进⾏换出。
有点不清楚。
就是每次发⽣缺页就将最早进⼊内存的页⾯换出,然后将刚调⼊的页⾯换⼊该物理块。
2.3 最近最久未使⽤(LRU)置换算法:LRU算法是缺页中断发⽣时选择最久未使⽤的页⾯进⾏换出。
这个算法其实也很好判断。
分享⼀个⼩技巧。
内存分配了k个物理块,发⽣缺页中断将要往内存调⼊某个页⾯的时候,在该页⾯往前⾯数K个物理块最前⾯的那个就会是要换出的,因为该页⾯最长时间未被使⽤过。
操作系统程序设计(编程描述页面置换算法——先进先出算法 )
nRunTime=runtime;//运行时间(运行步数)
PageTable=new page[nPageCountLogicalSpace];//根据实际需要创建页表
public page[] PageTable=new page[200];
public void InitProcess(int no,int pagetotal,int runtime)
{
nControlNo=no;
}
//模拟成功信息提示
private void hua(int x ,int y,Color n)
{
Graphics h = this.CreateGraphics(); //创建画布
Brush g = new SolidBrush(n);//创建画刷
sf.Alignment = StringAlignment.Near;
//设置字体格式
Brush g =new SolidBrush(n);
Graphics h = this.groupBox1.CreateGraphics(); //创建画布
g.Dispose();
}
//在groupbox1指定位置着色
private void sc()
{
StringFormat sf = new StringFormat();
h.DrawString(s, new Font(new FontFamily("黑体"), 8), g, x, y, sf);
}
//以groupBox1为画板指定坐标
页面置换算法模拟程序-附代码
目录1.问题的提出 (2)1.1关于页面置换算法模拟程序问题的产生 (2)1.2任务分析 (2)2.需求分析 (2)3.方案设计 (3)4.总体设计 (4)4.1程序N-S图 (4)4.2主要的函数 (4)4.3主要流程图及代码 (5)4.3.1 FIFO(先进先出) (5)4.3.2 LRU(最近最久未使用) (6)4.3.3 OPT(最佳置换算法) (8)4.4实现结果 (11)5.程序测试 (14)5.1设计测试数据 (14)5.2测试结果及分析 (15)摘要随着计算机的普及人们的物质生活得到了极大的满足,人们在精神生活方面同样也需要提高,所以越来越多的人进行着各种各样的学习。
操作系统是计算机教学中最重要的环节之一,也是计算机专业学生的一门重要的专业课程。
操作系统质量的好坏,直接影响整个计算机系统的性能和用户对计算机的使用。
一个精心设计的操作系统能极扩充计算机系统的功能,充分发挥系统中各种设备的使用效率,提高系统工作的可靠性。
由于操作系统涉及计算机系统中各种软硬件资源的管理,容比较繁琐,具有很强的实践性。
要学好这门课程,必须把理论与实践紧密结合,才能取得较好的学习效果.本课程设计是学生学习完《操作系统教程》课程后,进行的一次全面的综合训练,通过课程设计,让学生更好地掌握操作系统的原理及实现方法,加深对操作系统基础理论和重要算法的理解,加强学生的动手能力。
熟悉页面置换算法及其实现,引入计算机系统性能评价方法的概念。
关键词:编制页面置换算法模拟程序、打印页面、FIFO页面算法、LRU页面置换算法、OPT页面置换算法。
引言1.问题的提出1.1关于页面置换算法模拟程序问题的产生在各种存储器管理方式中,有一个共同的特点,即它们都要求将一个作业全部装入存方能运行,但是有两种情况:(1)有的作业很大,不能全部装入存,致使作业无法运行;(2)有大量作业要求运行,但存容量不足以容纳所有这些作业。
而虚拟存技术正式从逻辑上扩充存容量,将会解决以上两个问题。
操作系统实验:死锁避免,内存分配,页面置换
1.死锁避免#include<iostream>using namespace std;#define MAX_P 10 //最多的进程数#define MAX_R 20 //最多的资源int Avai[MAX_R]; //可利用资源向量int Max[MAX_P][MAX_R]; //最大需求矩阵int Allo[MAX_P][MAX_R]; //分配矩阵int Need[MAX_P][MAX_R]; //需求矩阵int Request[MAX_P][MAX_R]; //请求矩阵bool Finish[MAX_P];int p[MAX_P];int m,n;void Bank(); // 银行家bool SafeTest(); //定义一个安全序列检测函数int main(){int i,j,neednumber;cout<<"输入进程数和资源数"<<endl;cin>>m>>n;cout<<"输入最大需求矩阵MAX:"<<endl; //输入需求矩阵for(i=0;i<m;i++)for(j=0;j<n;j++)cin>>Max[i][j];cout<<"输入分配矩阵Allocation:"<<endl;for(i=0;i<m;i++){for(j=0;j<n;j++){cin>>Allo[i][j];Need[i][j]=Max[i][j]-Allo[i][j];}}cout<<"输入当前可使用的资源:"<<endl;for(i=0;i<n;i++) cin>>Avai[i];SafeTest();Bank();return 0;}void Bank(){int i,neednumber;char again;while(1){cout<<"输入请求进程"<<endl;cin>>neednumber;cout<<"输入要分配的资源"<<endl;for(i=0;i<n;i++) cin>>Request[neednumber][i];for(i=0;i<n;i++){Avai[i]-=Request[neednumber][i];//系统试探把资源分配给进程pi 可用的减去请求的Allo[neednumber][i]+=Request[neednumber][i];// 修改数据结构中的数值已分配的加上刚已分配了的Need[neednumber][i]-=Request[neednumber][i];// 需要的资源就减少}if(SafeTest()) cout<<"安全"<<endl; //检查一次看能不能成功else{cout<<"危险"<<endl;for(i=0;i<n;i++){Avai[i]+=Request[neednumber][i];Allo[neednumber][i]-=Request[neednumber][i];Need[neednumber][i]+=Request[neednumber][i];}}break;}}bool SafeTest(){int i,j,k,l=0;int Work[MAX_R];for(i=0;i<n;i++) Work[i]=Avai[i];for(i=0;i<m;i++) Finish[i]=false; //先把每个Finish赋初值falsefor(i=0;i<m;i++){if(Finish[i]==true) continue;else{for(j=0;j<n;j++){if(Need[i][j]>Work[j]) break; //出现资源不够}if(j==n){Finish[i]=true; //如果能满足资源每个finish为true 并把释放的资源加起来for(k=0;k<n;k++) Work[k]+=Allo[i][k];p[l++]=i;i=-1;}else continue;}if(l==m){cout<<"可有以下安全序列:"<<endl;for(i=0;i<l;i++){cout<<"P"<<p[i];if(i!=l-1) cout<<"-->";}cout<<""<<endl;return true;break;}}cout<<"会产生死锁"<<endl;return false;}2.内存分配#include <iostream>using namespace std;int aviliable=1024;int C[1024]; //创建内存int m[10]= {0,0,0,0,0,0,0,0,0,0};//int fenpei_and_release(int s);struct Node{int flag;//标识0表示释放(空闲)int length;//分区长度int C_name;//进程作业号int startAdd;//起始地址int used_of_neicun;//使用的空间Node * next; //};int menu(){int i;cout<<"(1):-1. 退出\n";cout<<"(2): 0. 分配内存\n";//printf("3. 显示内存使用情况\n");cout<<"(3):输入一个不小于1的运行时间回收内存\n";cout<<"\n请输入选择:";cin >>i;return i;}int main(){Node *head,*q,*p;head =new Node;//内存初始化head->flag=0;head->length=1024;head->next=NULL;head->C_name=-1;head->startAdd=0;head->used_of_neicun=0;int No,l,t,i,s,count=0,mul=1;while(1){int s;//menu();s=menu();if(s==-1) break;else if(s==0){cout<<"输入进程作业号(No) 进程需要的空间(length)进程所执行的时间(time)"<<endl;cin>>No>>l>>t;//cout<<"No ="<<No<<" l ="<<l<<" t ="<<t<<endl;i=1;//cout<<"hello world 1"<<endl;while(i>l || 2*i <l) i*=2;if(2*i>aviliable) cout<<"内存不足,请求失败!"<<endl;else if(No>9 || m[No]==1) cout<<"无效的进程作业号或者该进程已经存在"<<endl;else{//分配内存p=head;// while(p->length <= l || p->flag==1 ) p=p->next;while(p->length/2 >=l)//分配合适的空间{p->length=p->length/2;//长度除以2q=new Node;q->flag=0;q->used_of_neicun=0;q->length=p->length;q->startAdd=p->startAdd+p->length;q->C_name=-1;//没有被分配(或者已经释放)q->next=p->next;p->next=q;}if(p!=NULL){p->C_name=No;//进程作业号m[No]=1;//数组置位1,用来记录第No个进程已经存在p->flag=1;C[p->startAdd]=t;p->used_of_neicun=l;aviliable=aviliable-(p->length);//cout<<" aviliable ="<<aviliable<<endl;}else cout<<"内存不足"<<endl;for(i=1,p=head; p!=NULL; p=p->next,i++){if(p->flag==1){cout<<"分配成功!"<<endl<<endl<<"分配信息如下:"<<endl;cout<<"第"<<i<<"片内存已经被第"<<p->C_name<<"号进程占用"<<endl;cout<<"该进程所需内存大小为: "<<p->used_of_neicun<<endl;cout<<"该进程占用内存大小为: "<<p->length<<endl;cout<<"该进程所要占用CPU运行的时间为:"<<C[p->startAdd]<<"秒"<<endl<<endl;}}cout<<"此时剩余课分配内存空间为"<<aviliable<<"k"<<endl;//count=1024-aviliable-l;//cout<<"此时产生了"<<count<<"k的碎片不能使用"<<endl;}}else if(s>=1) //输入一个运行的时间来释放内存{for(p=head; p!=NULL; p=p->next){if(C[p->startAdd]>s) //时间满足运行条件C[p->startAdd]=C[p->startAdd]-s;elseC[p->startAdd]=0;}cout<<"CPU运行了"<<s<<"秒"<<endl<<endl;for(i=1,p=head; p!=NULL; p=p->next,i++){//cout<<" p= "<<p<<endl;//cout<<"hello world 1, 已进入释放循环1"<<endl;//cout<<NC[p->startAdd]<<"----"<<p->C_name<<"----"<<p->used_of_neicun<<endl;if(C[p->startAdd]==0&&p->C_name!=-1&&p->used_of_neicun!=0){//cout<<"hello world 2, 已进入释放循环2"<<endl;aviliable=aviliable+p->length;cout<<"第"<<i<<"片内存已经被释放,第"<<p->C_name<<"号进程已经运行结束!"<<endl;cout<<"此时有"<<aviliable<<"k的空闲空间"<<endl<<endl;p->flag=0;m[p->C_name]=0;p->C_name=-1;p->used_of_neicun=0;}// else cout<<"输入的时间不足以完成某个进程,没有内存释放"<<endl;} //释放与回收空间for(i=1,p=head; p->next!=NULL; i++){//合并空闲空间q=p->next;if( p->flag==0 && q->flag==0 && p->length==q->length ){p->next=q->next;p->length=p->length*2;delete q;cout<<"第"<<i<<"片内存已经和第"<<i+1<<"片内存合并,这片内存空间为大小为:"<<p->length<<"k"<<endl<<endl;}else p=p->next;}}}}3.页面置换(FIFO ,LRU ,FTO)#include<iostream>#include <stdlib.h>#include <time.h>#include <stdio.h>using namespace std;#define L 30//页面走向长度最大为20int M=4; //内存块struct P//定义一个结构体{int num,time;};int Input(int m,P p[L])//打印页面走向状态{m=30;int i,j;j=time(NULL);//取时钟时间srand(j);//以时钟时间x为种子,初始化随机数发生器cout<<"页面走向: ";for(i=0; i<m; i++){p[i].num=rand( )%10;//产生1到10之间的随即数放到数组p中p[i].time=0;cout<<p[i].num<<"";}cout<<endl;return m;}void print(P *page1)//打印当前的页面{P *page=new P[M];page=page1;for(int i=0; i<M; i++)cout<<page[i].num<<"";cout<<endl;}int Search(int e,P *page1 )//寻找内存块中与e相同的块号{P *page=new P[M];page=page1;for(int i=0; i<M; i++)if(e==page[i].num)return i; //返回i值}int Max(P *page1)//寻找最近最长未使用的页面用于OPT算法{P *page=new P[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(P *page1,int i,int t,P p[L])//记录当前内存块中页面离下次使用间隔长度用于OPT 算法{P *page=new P[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=1;int m=0,t=0;float n=0;//缺页次数P p[L];m=Input(m,p);//调用input函数,返回m值M=4;P *page=new P[M];//dowhile(c==1||c==2||c==3){int i=0;for(i=0; i<M; i++) //初试化页面基本情况{page[i].num=0;page[i].time=m-1-i;}cout<<"1:FIFO页面置换"<<endl;cout<<"2:LRU页面置换"<<endl;cout<<"3:OPT页面置换"<<endl;cout<<"按其它键结束程序;"<<endl;cin>>c;if(c==1)//FIFO页面置换先进先出//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<<"缺页次数:"<<n<<" 缺页率:"<<n<<"/"<<m<<" = "<<n/m<<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;//把与它相同的内存块的时间置0for(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<<"缺页次数:"<<n<<" 缺页率:"<<n<<"/"<<m<<" = "<<n/m<<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);//记录下最大的count,即为要替换的页s=t;}//把找到的块号赋给spage[s].num=p[i].num;//替换n++; //cout<<p[i].num<<"";print(page);i++;}}}cout<<"缺页次数:"<<n<<" 缺页率:"<<n<<"/"<<m<<" = "<<n/m<<endl;}}//while(c==1||c==2||c==3);return 0;}。
页面置换算法 实验报告
一个周期内访问该页面的次数,time为访问时间;pl[total_vp]为页面 结构数组,由于共有320条指令,每页可装入10条指令,因此虚页长 total_vp的值为32。
可为每个页面设置一个步长变量其初值为一足够大的数对于不在内存的页面将其值重置为零对于位于内存的页面其值重置为当前访问页面与之后首次出现该页面时两者之间的距离因此该值越大表示该页是在最长时间内不再被访问的页面可以选择其作为换出页面
综合性实验报告
专业 年级 课程名称 操作系统 学号姓名 实验地点
班级:
项目名称 页面置换算法
为有效
pl[page[i]].time=present_time; //修改页面的访问时
间
freepf_head=freepf_head->next; //减少一个free 页
面
}
else
pl[page[i]].time=present_time; //命中则修改该单元
的访问时间
present_time++;
}
printf("LRU:%6.4f ",1-(float)diseffect/320);
}
void OPT(int total_pf) /* 最佳页面置换算法 */
{
int i,j,max,maxpage,d,dist[total_vp];
initialize(total_pf);
for(i=0;i<total_instruction;i++)
操作系统之页面置换算法(最佳置换OPT,先进先出FIFO,最近最久未使用LRU)
操作系统之页⾯置换算法(最佳置换OPT,先进先出FIFO,最近最久未使⽤LRU)最近学习操作系统时,实验要求实现常见的三种页⾯置换算法,博主按照书上要求试着编写,实现了案例,并记录在博客随记中,以便后续⾃⼰复习并也给需要的同学分享参考⼀下!⽔平有限,若有错,请悄悄告诉博主!博主好⽴即改正。
最佳置换算法(optimal replacement,OPT)是从内存中选择今后不再访问的页⾯或者在最长⼀段时间后才需要访问的页⾯进⾏淘汰。
如下例⼦:根据页⾯⾛向依次处理,得到最终的置换结果如下图表,整个页⾯缺页次数为7,缺页率为7/12=58%。
1 #include <iostream>2 #include <stdio.h>3 #include <stdlib.h>4#define N 125#define B 36using namespace std;78int pageArr[N]={1,2,3,4,1,2,5,1,2,3,4,5};//页⾯⾛向9int block[B]={0};//物理块3个,其数值是页号10 typedef struct FLAG {11int flags[B];12int counts;13 } FLAG;1415void opt(int pageArr[],int block[]);16int inBlock(int which);17int findFar(int next);18void Replace(int index,int value);19void disPlay();2021int main(void){22 cout << "begin:" <<endl;23 opt(pageArr,block);24 cout << "end!" <<endl;25return0;26 }2728void opt(int pageArr[],int block[]){29int getIndex;30for(int i=0;i<N;i++){31if(i<3){//前3页号#短缺#进队列32 block[i]=pageArr[i];33 printf("缺页:(null)-->%d\n",pageArr[i]);34 }35else {36if(i==3){37 disPlay();3839 }40if(inBlock(pageArr[i])!=-1){//下⼀个页⾯if在物理块中返回index并跳过,反-141 disPlay();4243continue;44 }45 getIndex=findFar(i+1);//从下⼀个页号,找到最远出现的页⾯,替换的下标46if(getIndex==-1){47 cout<<"error,not replace obj!"<<'\t';48 }49else{50 Replace(getIndex,pageArr[i]);//由下标找到上⼀组替换⽬标,⽤第⼆参数替换51 disPlay();5253 }54 }55 }56return;57 }5859//替换block中的物理块60void Replace(int index,int value){61 printf("缺页:%d--被替换为-->%d\n",block[index],value);62 block[index]=value;63return;64 }656667//找到最远出现的页⾯68int findFar(int next){69int index=-1;//error,默认返回不存在的索引70 FLAG myflag;71 myflag.flags[0]=0;72 myflag.flags[1]=0;73 myflag.flags[2]=0;74 myflag.counts=0;75int stop = N-next;76while(stop--){77 index=inBlock(pageArr[next++]);78if(index!=-1){79 myflag.flags[index]=1;80 myflag.counts++;83break;84 }85 }86for(index=0;index<B;index++){87if(myflag.flags[index]==0)88break;89 }90return index;91 }929394//下⼀个页⾯if在物理块中返回index,反-195int inBlock(int which){96//int i=0;97//while(i<B)98// if(block[i++]==which)99// return i-1;100for(int i=0;i<B;i++){101if(block[i]==which)102return i;103 }104return -1;105 }106107//打印⼀元组108void disPlay(){109int i=0;110while(i<B){111 printf("%d\t",block[i++]);112 }113 printf("\n");114return;115 }上⾯是博主使⽤C++(基本是C语法)编写的代码,运⾏结果如下://////////////////////////////////////////////////////////////////////////begin:缺页:(null)-->1缺页:(null)-->2缺页:(null)-->31 2 3缺页:3--被替换为-->41 2 41 2 41 2 4缺页:4--被替换为-->51 2 51 2 51 2 5缺页:1--被替换为-->33 2 5缺页:3--被替换为-->44 2 54 2 5end!//////////////////////////////////////////////////////////////////////////先进先出算法:先进先出置换算法(first in first out,FIFO)是淘汰最先进⼊内存的页⾯,即选择在内存中驻留时间最长的页⾯进⾏淘汰的算法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <stdio.h>#include <stdlib.h>#include <conio.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);int main(){int i,k,code;printf(" ╔═══════════════╗\n");printf(" ║页面置换算法║\n");printf(" ╚═══════════════╝\n");printf("请输入物理块的个数(M<=10):");scanf("%d",&mSIZE);printf("请输入页面号引用串的个数(P<=100):");scanf("%d",&pSIZE);puts("请依次输入页面号引用串(连续输入,无需隔开):");for(i=0;i<pSIZE;i++)scanf("%1d",&page[i]);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:exit(0);default:printf("输入错误,请重新输入:");}printf("按任意键重新选择置换算法:>>>");getch();system("cls");}while(code!=4);return 0;}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];}}printf("\n\n利用先进先出(FIFO)算法的置换图\n\n");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];}}printf("\n\n利用最近最久未使用(LRU)算法的置换图\n\n");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];}}printf("\n\n利用最佳置换算法(OPT)算法的置换图\n\n");print(count);}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");}。