请求分页存储管理模拟实验
请求分页实验报告
一、实验目的1. 理解请求分页的基本原理和实现方法。
2. 掌握操作系统内存管理的基本知识。
3. 提高编程能力和系统设计能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:C/C++3. 开发环境:Visual Studio 2019三、实验原理请求分页是一种内存管理策略,其基本思想是当进程访问内存中的某页时,如果该页不在内存中,则从磁盘读取该页到内存,并将内存中的一部分页调出磁盘。
请求分页可以提高内存的利用率,避免内存碎片。
四、实验内容1. 设计请求分页系统2. 实现请求分页算法3. 测试请求分页系统的性能五、实验步骤1. 设计请求分页系统(1)定义数据结构定义进程结构体、内存块结构体、页面表结构体等。
(2)初始化系统初始化内存块、页面表、进程队列等。
(3)请求分页算法实现实现FIFO、LRU、LFU等请求分页算法。
2. 实现请求分页算法(1)FIFO算法FIFO(先进先出)算法是最简单的请求分页算法,当请求分页时,总是选择最先进入内存的页面调出。
(2)LRU算法LRU(最近最少使用)算法选择最近最少被访问的页面调出,可以有效减少缺页中断。
(3)LFU算法LFU(最少使用频率)算法选择使用频率最低的页面调出,适用于页面使用频率不均匀的情况。
3. 测试请求分页系统的性能(1)定义测试用例设计一系列测试用例,包括不同大小的进程、不同类型的页面访问模式等。
(2)运行测试用例运行测试用例,记录缺页中断次数、页面命中率等性能指标。
(3)分析结果分析测试结果,比较不同请求分页算法的性能。
六、实验结果与分析1. 实验结果通过实验,我们得到了以下结果:(1)FIFO算法:缺页中断次数为50,页面命中率为90%。
(2)LRU算法:缺页中断次数为30,页面命中率为95%。
(3)LFU算法:缺页中断次数为35,页面命中率为92%。
2. 分析结果从实验结果可以看出,LRU算法在三种算法中性能最好,其次是LFU算法,FIFO算法性能最差。
操作系统实验4-请求分页存储管理模拟实验
实验四请求分页存储管理模拟实验一:实验目得通过对页面、页表、地址转换与页面置换过程得模拟,加深对请求分页存储管理系统得原理与实现技术得理解.二:实验内容假设每个页面可以存放10条指令,分配给进程得存储块数为4。
用C语言或Pascal语言模拟一进程得执行过程。
设该进程共有320条指令,地址空间为32个页面,运行前所有页面均没有调入内存。
模拟运行时,如果所访问得指令已经在内存,则显示其物理地址,并转下一条指令;如果所访问得指令还未装入内存,则发生缺页,此时需要记录缺页产生次数,并将相应页面调入内存,如果4个内存块已满,则需要进行页面置换。
最后显示其物理地址,并转下一条指令。
在所有指令执行完毕后,显示进程运行过程中得缺页次数与缺页率.页面置换算法:分别采用OPT、FIFO、LRU三种算法。
进程中得指令访问次序按如下原则生成:50%得指令就是顺序执行得。
25%得指令就是均匀分布在低地址部分.25%得指令就是均匀分布在高地址部分.三:实验类别分页存储管理四:实验类型模拟实验五:主要仪器计算机六:结果OPT:LRU:FIFO:七:程序# i nclude 〈stdio 、h 〉# incl ude 〈stdlib 、h 〉# include 〈conio 、h># def ine blockn um 4//页面尺寸大小int m; //程序计数器,用来记录按次序执行得指令对应得页号s ta ti c in t num [320]; //用来存储320条指令typedef s truct BLOCK //声明一种新类型—-物理块类型{ﻩint pagenum; //页号ﻩint acces sed; //访问量,其值表示多久未被访问}BLOCK ;BLOCK bl ock [bl ocknum ]; //定义一大小为8得物理块数组void init () //程序初始化函数,对bl ock 初始化{for (int i=0;i <blo cknum;i++)block[i]、pagenum=—1;block[i]、accessed=0;ﻩm=0;}}int pageExist(int curpage)//查找物理块中页面就是否存在,寻找该页面curpage就是否在内存块block中,若在,返回块号{ﻩfor(int i=0;i<blocknum; i++)ﻩ{ﻩﻩif(block[i]、pagenum == curpage )ﻩﻩreturn i; //在内存块block中,返回块号ﻩ}return -1;}int findSpace()//查找就是否有空闲物理块,寻找空闲块block,返回其块号{for(int i=0;i<blocknum;i++)ﻩ{if(block[i]、pagenum==-1)ﻩreturn i;//找到了空闲得block,返回块号}ﻩreturn -1;}int findReplace()//查找应予置换得页面{ﻩint pos = 0;ﻩfor(int i=0;i〈blocknum;i++){if(block[i]、accessed 〉block[pos]、accessed)ﻩpos = i; //找到应该置换页面,返回BLOCK中位置ﻩ}return pos;}void display()//显示物理块中得页面号{ﻩﻩfor(int i=0; i〈blocknum; i++)ﻩ{ﻩif(block[i]、pagenum != -1)ﻩ{ﻩﻩprintf(” %02d ",block[i]、pagenum);ﻩﻩﻩprintf("%p |”,&block[i]、pagenum);ﻩﻩ}printf("\n");}void randam()//产生320条随机数,显示并存储到num[320]{int flag=0;printf(”请为一进程输入起始执行指令得序号(0~320):\n”);ﻩscanf("%d",&m);//用户决定得起始执行指令printf("******进程中指令访问次序如下:(由随机数产生)*******\n");for(int i=0;i〈320;i++){//进程中得320条指令访问次序得生成ﻩﻩnum[i]=m;//当前执行得指令数,ﻩﻩif(flag%2==0)ﻩm=++m%320;//顺序执行下一条指令ﻩﻩif(flag==1)ﻩﻩm=rand()%(m-1);//通过随机数,跳转到低地址部分[0,m—1]得一条指令处,设其序号为m1if(flag==3)ﻩﻩm=m+1+(rand()%(320-(m+1)));//通过随机数,跳转到高地址部分[m1+2,319]得一条指令处,设其序号为m2ﻩﻩflag=++flag%4;ﻩprintf(” %03d”,num[i]);//输出格式:3位数ﻩﻩif((i+1)%10==0)//控制换行,每个页面可以存放10条指令,共32个页面ﻩprintf(”\n”);}}void pagestring() //显示调用得页面序列,求出此进程按次序执行得各指令所在得页面号并显示输出{for(int i=0;i〈320;i++)ﻩ{printf(”%02d",num[i]/10);//输出格式:2位数if((i+1)%10==0)//控制换行,每个页面可以存放10条指令,共32个页面ﻩﻩprintf("\n”);}}void OPT() //最佳替换算法{ﻩint n=0;//记录缺页次数int exist,space,position;ﻩintcurpage;//当前指令得页面号ﻩfor(int i=0;i<320;i++)ﻩ{ﻩm=num[i];ﻩcurpage=m/10;ﻩﻩexist=pageExist(curpage);ﻩif(exist==-1)ﻩﻩ{ //当前指令得页面号不在物理块中space=findSpace();ﻩﻩif(space != -1)ﻩﻩ{//当前存在空闲得物理块ﻩﻩblock[space]、pagenum= curpage;//将此页面调入内存ﻩﻩﻩdisplay();//显示物理块中得页面号ﻩﻩn++;//缺页次数+1ﻩ}ﻩﻩelseﻩﻩ{ //当前不存在空闲得物理块,需要进行页面置换for(intk=0;k<blocknum;k++)ﻩﻩﻩﻩ{for(int j=i;j〈320;j++)ﻩ{//找到在最长(未来)时间内不再被访问得页面ﻩﻩﻩﻩif(block[k]、pagenum!= num[j]/10)ﻩﻩﻩ{ﻩﻩblock[k]、accessed = 1000;ﻩﻩﻩ} //将来不会被访问,设置为一个很大数ﻩﻩﻩelseﻩﻩﻩ{ //将来会被访问,访问量设为jﻩﻩﻩblock[k]、accessed = j;ﻩﻩﻩﻩﻩbreak;ﻩﻩﻩﻩ}ﻩﻩﻩ}ﻩ}ﻩposition = findReplace();//找到被置换得页面,淘汰ﻩblock[position]、pagenum = curpage;// 将新页面调入display();ﻩﻩn++; //缺页次数+1ﻩ}}ﻩ}ﻩprintf(”缺页次数:%d\n",n);printf("缺页率:%f%%\n",(n/320、0)*100);}void LRU() //最近最久未使用算法{int n=0;//记录缺页次数ﻩint exist,space,position ;ﻩint curpage;//当前指令得页面号ﻩfor(int i=0;i<320;i++)ﻩ{ﻩm=num[i];ﻩﻩcurpage=m/10;ﻩexist = pageExist(curpage);ﻩif(exist==-1)ﻩﻩ{ //当前指令得页面号不在物理块中space = findSpace();ﻩﻩif(space!= —1)ﻩ{ //当前存在空闲得物理块ﻩﻩblock[space]、pagenum = curpage;//将此页面调入内存ﻩﻩdisplay();//显示物理块中得页面号ﻩn++;//缺页次数+1ﻩﻩ}else{ //当前不存在空闲得物理块,需要进行页面置换ﻩﻩposition= findReplace();ﻩblock[position]、pagenum = curpage;ﻩﻩdisplay();ﻩn++;//缺页次数+1ﻩ}ﻩﻩ}elseﻩﻩblock[exist]、accessed = -1;//恢复存在得并刚访问过得BLOCK中页面accessed为-1for(int j=0; j<blocknum; j++)ﻩﻩ{//其余得accessed++ﻩﻩblock[j]、accessed++;}ﻩ}printf("缺页次数:%d\n”,n);ﻩprintf("缺页率:%f%%\n",(n/320、0)*100);}void FIFO(){int n=0;//记录缺页次数int exist,space,position ;ﻩ int curpage;//当前指令得页面号int blockpointer=-1;for(int i=0;i<320;i++)ﻩ{ﻩ m=num[i];curpage=m/10;ﻩexist = pageExist(curpage);ﻩ if(exist==-1){//当前指令得页面号不在物理块中ﻩ space = findSpace();ﻩﻩif(space !=-1)ﻩ { //当前存在空闲得物理块ﻩﻩ blockpointer++;ﻩﻩﻩblock[space]、pagenum=curpage; //将此页面调入内存ﻩ n++;//缺页次数+1ﻩﻩﻩ display();//显示物理块中得页面号ﻩ}ﻩ elseﻩ { //没有空闲物理块,进行置换ﻩﻩﻩﻩposition = (++blockpointer)%4;ﻩ block[position]、pagenum = curpage;//将此页面调入内存ﻩﻩn++;ﻩﻩ display();ﻩ}ﻩ }}printf("缺页次数:%d\n",n);printf("缺页率:%f%%\n",(n/320、0)*100);}void main(){ﻩint choice;ﻩprintf("************请求分页存储管理模拟系统*************\n");ﻩrandam();printf("************此进程得页面调用序列如下**************\n”);pagestring();ﻩwhile(choice!= 4){ﻩﻩprintf("********1:OPT 2:LRU 3:FIFO 4:退出*********\n”);ﻩprintf("请选择一种页面置换算法:”);ﻩscanf("%d",&choice);ﻩinit();ﻩswitch(choice)ﻩ{ﻩcase 1:ﻩﻩﻩprintf(”最佳置换算法OPT:\n");ﻩprintf("页面号物理地址页面号物理地址页面号物理地址页面号物理地址\n");ﻩﻩﻩOPT();ﻩbreak;ﻩcase 2:ﻩﻩprintf("最近最久未使用置换算法LRU:\n");ﻩprintf("页面号物理地址页面号物理地址页面号物理地址页面号物理地址\n");ﻩLRU();ﻩﻩﻩbreak;ﻩﻩcase 3:ﻩprintf("先进先出置换算法FIFO:\n");ﻩprintf("页面号物理地址页面号物理地址页面号物理地址页面号物理地址\n");FIFO();ﻩﻩbreak;ﻩ}}}。
操作系统-请求页式存储管理实验报告分析解析
操作系统-请求页式存储管理实验报告分析解析实验背景在计算机系统中,内存是一项很重要的资源。
其中,操作系统需要管理内存,以便为用户进程和内核提供适当的内存空间。
页式内存管理是操作系统能够管理和维护内存的一种方式。
在页式内存管理中,主存分为固定大小的框架,称为页框,而进程的地址空间被分割为固定大小的页。
页式内存管理系统采用了一种称为“请求页式存储”的技术,允许进程只存取正在使用的那些页面。
这样可以节省空间,并且提高了处理器访问内存的速度。
实验环境本次实验使用的操作系统是 Ubuntu 20.04 LTS 操作系统。
实验目标本次实验的主要目标是通过模拟请求页式内存管理系统,来了解和深入理解页式内存管理技术。
本次实验需要完成以下任务:1.编写一个简单的请求页式存储模拟器;2.使用该模拟器对作业和内存进行模拟;3.分析模拟结果并撰写实验报告。
实验过程阅读并理解作业说明在开始实验之前,我们首先需要阅读和了解具体的作业说明。
在本次实验中,我们需要完成一个请求页式存储模拟器,以及使用该模拟器对作业与内存进行模拟。
编写模拟器在了解了作业说明后,我们开始按照作业的要求,编写请求页式内存管理模拟器。
在这里,我们需要使用到Python 编程语言。
实际上,我们在编写该模拟器时,主要分为以下几步:1.文件操作:首先,我们需要通过读取文件中的数据来模拟进程对内存的请求。
在输入文件中,每一行表示一个请求,包含了进程 ID、请求的地址和访问类型。
2.内存分配:接着,我们需要模拟请求页式内存管理系统中对于内存分配的操作,即在访问时,将需要的页加载到内存中,如果内存已满,则需要选择一个页面将其从内存中移除,为新的页面腾出空间。
3.页面置换:如果进行页面置换,则需要选出最久未访问的页面并移出内存,空出空间用于新的页面,这就是所谓的“最久未使用”(LRU)策略。
进行模拟有了模拟器之后,我们就可以针对不同的作业和内存大小进行实验。
在实验的过程中,我们可以观察不同大小的内存和不同的作业怎样影响模拟的结果。
实验六请求分页存储管理
实验六:请求分页存储管理一.实验目的深入理解请求页式存储管理的基本概念和实现方法,重点认识其中的地址变换、缺页中断、置换算法等实现思想。
二.实验属性该实验为综合性、设计性实验。
三.实验仪器设备及器材普通PC386以上微机四.实验要求本实验要求2学时完成。
本实验要求完成如下任务:(1)建立相关的数据结构:页表、页表寄存器、存储块表等;(2)指定分配给进程的内存物理块数,设定进程的页面访问顺序;(3)设计页面置换算法,可以选择OPT、FIFO、LRU等,并计算相应的缺页率,以比较它们的优劣;(4)编写地址转换函数,实现通过查找页表完成逻辑地址到物理地址的转换;若发生缺页则选择某种置换算法(OPT、FIFO、LRU等)完成页面的交换;(5)将整个过程可视化显示出来。
实验前应复习实验中所涉及的理论知识和算法,针对实验要求完成基本代码编写并完成预习报告、实验中认真调试所编代码并进行必要的测试、记录并分析实验结果。
实验后认真书写符合规范格式的实验报告(参见附录A),并要求用正规的实验报告纸和封面装订整齐,按时上交。
三、设计过程3.1算法原理分析OPT算法是未来最远出现,当当前内存中没有正要访问的页面时,置换出当前页面中在未来的访问页中最远出现的页面或再也不出现的页面。
FIFO算法是先进先出,当当前内存中没有正要访问的页面时,置换出最先进来的页面。
LRU算法是最近最久未使用,当当前内存中没有正要访问的页面时,置换出在当前页面中最近最久没有使用的页面。
3.2数据定义int length,num_page,count,seed; //length记录访问串的长度,num_page页面数,count记录缺页次数int result[20][30],order[30],a[10]; //result记录结果,order存储访问串,a存储当前页面中的值int pos1,flag1,flag2,flag3; //pos1位置变量,flag1等为标志变量 char result1[30]; //记录缺页数组 void opt() //最佳void fifo() //先进先出bool search(int n) //查找当前内存中是否已存在该页3.3流程图与运行截图图6.1 FIFO ()函数流程图;否是 是否 开始得到执行的指令指令是否在内存中最先存入指令被淘汰下面是否还有指令 结束得出命中率图2.2 OPT算法流程图四、小结本次课程设计目的是通过请求页式管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。
基本分页存储管理的模拟实现
基本分页存储管理的模拟实现学院:专业:学生姓名:学号:指导教师:2014年3月 18 日目录一、设计内容 (2)二、相关操作系统的知识介绍 (2)三、课程设计的目的及要求 (2)四、程序功能说明 (3)五、算法整体思想 (3)六、主要功能模块进程图 (3)七、实验结果 (4)八、实验总结 (7)九、程序代码 (7)一、设计内容根据设计要求实现对基本分页存储管理的模拟二、相关操作系统的知识介绍连续分配方式会形成许多“碎片”,虽然可通过“紧凑”方法将许多碎片拼接成可用的大块空间,但须为之付出很大的开销。
如果允许将一个进程直接分散的装入到许多不相邻接的分区中,则无需在进行“紧凑”。
基于这一思想而产生了离散分配方式。
如果离散分配的基本单位是页,则称为分页存储管理方式;如果离散分配的基本单位是段,则称为分段存储管理方式。
在分页存储管理方式中,如果不具备页面对换功能,则称为基本的分页存储管理方式,或称为纯分页存储管理方式,它不具有支持实现虚拟存储的功能,它要求把每个作业全部装入内存后方能运行。
三、课程设计的目的及要求1、课程设计的目的操作系统课程设计是计算机专业重要的教学环节,它为我们提供了一个既动手又动脑,将课本上的理论知识和实际有机的结合起来,独立分析和解决实际问题的机会。
●进一步巩固和复习操作系统的基础知识。
●培养我们结构化程序、模块化程序设计的方法和能力。
●提高我们调试程序的技巧和软件设计的能力。
●提高我们分析问题、解决问题以及综合利用 C 语言进行程序设计的能力。
2、设计要求1.选择恰当的数据结构表示页表2.进程名,进程所需页数,进程进行的操作(装入/退出)等操作可有键盘输入,也可从文件读出。
3.每进行一次进程的装入或者退出操作,就显示出操作执行后内存中各页的分配情况。
四、程序功能说明函数各模块部分功能void CreatA()//创建内存新函数void NewNode(LinkList &L)//建立新进程void FreeNode(LinkList &L)//回收进程,释放内存void Printf(LinkList L)//显示所有进程所占物理块信息void look(LinkList L)//查看进程信息void showit()//显示内存块使用信息函数的整体功能这个程序是为了实现离散分配方式,以消减内存的外零头,提高内存的利用率,由系统把逻辑地址划分为页号和页内地址两部分。
操作系统课程设计模拟请求页式存储管理
操作系统课程设计报告项目:模拟请求页式存储管理一、目的和要求1、实训目的(1)通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解。
熟悉虚存管理的各种页面淘汰算法(2)通过编写和调试地址转换过程的模拟程序以加强对地址转换过程的了解。
2、实训要求编写并调试完成请求页式存储管理程序。
页面置换算法:最佳置换算法(OPT)、先进先出算法(FIFO)和最近最少用算法(LRU)。
要求打印每个页面置换算法的页面置换变化示意图、缺页中断次数和缺页中断率,以比较各种算法的优缺点。
二、设计思路及过程1、概要设计1.1 问题概述根据三种不同的置换算法(FIFO、LRU、OPT),依据其不同的算法方式,分别计算该页面引用串在不同算法下的缺页次数与缺页率,并显示各页面的变化情况。
1.2 内容分析对于该课程设计中模拟的请求页式存储管理的页面置换过程,只要掌握其中最基本的三种算法,包括FIFO、LRU及OPT。
另外,对于同一个页面引用串,要求能够调用不同的算法对它进行操作。
2、过程设计2.1模块设计在下图的主模块设计图中,只注重描绘了请求页式存储管理的三种主要算法,未描绘出细节部分。
图2.1 请求页式存储管理的主模块设计图2.2 算法原理分析要成功实现算法,首先要知道各个方法是怎么做的,即原理是怎样的,下面是三种算法的原理。
(1)FIFO算法:该算法认为刚被调入的页面在最近的将来被访问的可能性很大,而在主存中滞留时间最长的页面在最近的将来被访问的可能性很小。
因此。
FIFO算法总是淘汰最先进入主存的页面,即淘汰在主存中滞留时间最长的页面。
(2)LRU算法是最近最久未使用,当当前内存中没有正要访问的页面时,置换出在当前页面中最近最久没有使用的页面。
该算法总是选择最近一段时间内最长时间没有被访问过的页面调出。
它认为那些刚被访问过的页面可能在最近的将来还会经常访问他们,而那些在较长时间里未被访问的页面,一般在最近的将来再被访问的可能性较小。
请求分页管理实验报告
请求分页管理实验报告1.实验目的请求页式管理是一种常用的虚拟存储管理技术。
本设计通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式管理的页面置换算法。
2.实验内容:通过随机数产生一个指令序列,共320条指令。
指令的地址按下述原则生成:① 50% 的指令是顺序执行的;② 25% 的指令是均匀分布在前地址部分;③ 25% 的指令是均匀分布在后地址部分。
具体的实施方法是:①在[0,319] 的指令地址之间随机选取一起点m;②顺序执行一条指令;③在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m′;④顺序执行一条指令,其地址为m′+1;⑤在后地址[m′+2,319] 中随机选取一条指令并执行;⑥重复上述步骤② ~ ⑤ ,直到执行320 次指令。
将指令序列变换成为页地址流设:①页面大小为1K;②用户内存容量为4 页到32 页;③用户虚存容量为32K 。
在用户虚存中,按每K 存放10 条指令排列虚存地址,即320 条指令在虚存中的存放方式为:第0 条~ 第9 条指令为第0 页( 对应虚存地址为[0,9]);第10 条~ 第19 条指令为第1 页( 对应虚存地址为[10,19] ) ;┇ ┇第310 条~ 第319 条指令为第31 页( 对应虚存地址为[310,319]) 。
计算并输出下述各种算法在不同内存容量下的命中率。
先进先出的算法(FIFO);最近最少使用算法(LRR);最少访问页面算法(LFR);最近最不经常使用算法(NUR)。
3.实验环境每个学生一台微机,需要安装windows98或windows2000操作系统,配备VC、VB、java或C编程语言,每个学生上机时间不少于24个小时。
(1)、分页请求系统是:(1)请求分页的页表机制。
它是在分页的页表机制上增加若干个项而形成的,作为请求分页的数据结构;(2)缺页中断机构。
每当用户程序要访问的页面尚未调入内存时,便产生一缺页中断,以请求OS将所缺的页面调入内存;(3)地址变换机构。
计算机操作系统实验_源码_模拟请求分页虚拟存储管理中的硬件地址变换过程[技巧]
地址变换算法框图如图10—1所示。
运行设计的地址变换程序 ,显示或打印运行结果。。因为只是模拟地址变换,并不
cin>>menu;
while(menu)
{
switch(menu)
{
case 1:
cout<<"请输入指令的逻辑地址:";
cin>>ins;
changeaddr(p,ins);
break;
case 2:
cout<<"谢谢使用,下次再见~"<<endl;
exit(0);
break;
default:
cout<<"输入有误,请重新输入~"<<endl;
cout<<"----------\t\t1.输入指令\t\t---------"<<endl;
cout<<"----------\t\t2.退出程序\t\t---------"<<endl;
cout<<"----------欢迎使用分页虚拟存储器硬件地址变换算法---------"<<endl;
cout<<endl<<"请输入您的选择:";
p[2].pno=2;p[2].flag=1;p[2].cno=9;p[2].modf=0;p[2].addr=013;
请求分页存储管理模拟实验
操作系统模拟实验实验名称:请求分页存储管理模拟实验实验目的:通过实验了解windows系统中的线程同步如何使用,进一步了解操作系统的同步机制。
实验内容:调用Windows API,模拟解决生产者-消费者问题;思考在两个线程函数中哪些是临界资源?哪些代码是临界区?哪些代码是进入临界区?哪些代码是退出临界区?进入临界区和退出临界区的代码是否成对出现?学习Windows API中的如何创建线程,互斥,临界区等。
程序运行结果:源程序:#include "stdAfx.h"//包含头文件以支持多线程#include "windows.h"#include "stdio.h"//用于标志所有的子线程是否结束//每次子线程结束后,此值便加1。
static long ThreadCompleted = 0;//互斥量HANDLE mutex;//信号量,用于生产者通知消费者HANDLE full;//信号量,用于消费者通知生产者HANDLE empty;//信号量,当所有的子线程结束后,通知主线程,可以结束。
HANDLE evtTerminate;//生产标志#define p_item 1//消费标志#define c_item 0//哨兵#define END 10//缓冲区最大长度const int max_buf_size=11;const int cur_size=10;//缓冲区定义int BUFFER[max_buf_size];//放消息指针int in=0;//取消息指针int out=0;int front=0;int tail=0;int sleep_time=1000;bool flag=true;//线程函数的标准格式unsigned long __stdcall p_Thread(void *theBuf);unsigned long __stdcall c_Thread(void *theBuf);//打印缓冲区内容void PrintBuf(int buf[],int buf_size);int main(int argc, char* argv[]){//初始化缓冲区unsigned long TID1, TID2;for(int i=0;i<cur_size;i++)BUFFER[i]=0;//互斥量和信号量的创建,函数用法可查看MSDNmutex=CreateMutex(NULL,false,"mutex");full=CreateSemaphore(NULL,0,1,"full");empty=CreateSemaphore(NULL,max_buf_size,max_buf_size,"empty");evtTerminate = CreateEvent(NULL, FALSE, FALSE, "Terminate");//创建一个生产者线程和消费者线程。
分页存储管理实验报告
分页存储管理实验报告分页存储管理实验报告篇一:分页存储管理的模拟实验上机报告分页存储管理的模拟实验上机报告页面管理的基本原理及方法:各进程的虚拟空间被划分成若干个长度相等的页(page)。
页长的划分和内存外存之间的数据传输速度以及内存大小等有关。
页式管理还把内存空间也按也的大小划分为页面(page frame)。
然后把页式虚拟地址与内存页面物理地址建立一一对应页表,并用相应的硬件地址变换机构,来解决离散地址变换问题。
在作业或进程开始执行之前,把该作业或进程的程序段和数据全部装入内存的各个页面中,并通过页表(page mapping table)和硬件地址变换机构实现虚拟地址到内存物理地址的地址映射。
1. 内存页面分配静态页面管理的第一步是为要求内存的作业或进程分配足够的页面。
系统依靠存储页面表,请求表及页表来完成内存的分配工作。
a. 页表页表由页号与页面号组成。
如右图所示页表的大小由进程或作业的长度决定。
例如,对于一个每页长1k,大小为20k的进程来说,如果一个内存单元存放一个页表项,则只要分配给该页表20个存储单元即可。
页式管理是每个进程至少拥有一个页表。
实验中对页表的定义如下(采用数组形式,数组下标表示页号,数组单元存放与数组下标(页号)相应的页面号):int pagetable[100] b.请求表(作业申请表)请求表用来确定作业或进程的虚拟空间的各页在内存中的对应位置。
为了完成这个认为,系统必须知道每个作业或进程的页表起始地址(本实验中假定为0)和长度,以进行内存分配和地址变换。
另外请求表中还包括每个作业或进程所要求的页面数。
请求表整个系统一张,实验中对请求表的定义如下(采用结构体数组形式,并将页表也作为其中一个成员(即域)):#define u 5 struct application_table{char name[8];/*作业名*/int size;/*作业大小――即将上表中的请求页面数改用字节表示*/int paddress; /*页表起始地址*/ int length;/*页表长度――以页面数表示*/int state; /*内存的分配状态,以分配的用1表示,未分配的用0表示*/int pagetable[100];/*页表,放在这里是为了方便虚地址转换及作业撤销的操作*/ }application[u];c.存储页面表(本实验中采用位示图法)位示图也是整个系统一张,它指出内存各页面是否已被分配出去,以及未分配页面的总数。
分页存储管理实验报告
分页存储管理实验报告篇一:分页存储管理的模拟实验上机报告分页存储管理的模拟实验上机报告页面管理的基本原理及方法:各进程的虚拟空间被划分成若干个长度相等的页(page)。
页长的划分和内存外存之间的数据传输速度以及内存大小等有关。
页式管理还把内存空间也按也的大小划分为页面(page frame)。
然后把页式虚拟地址与内存页面物理地址建立一一对应页表,并用相应的硬件地址变换机构,来解决离散地址变换问题。
在作业或进程开始执行之前,把该作业或进程的程序段和数据全部装入内存的各个页面中,并通过页表(page mapping table)和硬件地址变换机构实现虚拟地址到内存物理地址的地址映射。
1. 内存页面分配静态页面管理的第一步是为要求内存的作业或进程分配足够的页面。
系统依靠存储页面表,请求表及页表来完成内存的分配工作。
a. 页表页表由页号与页面号组成。
如右图所示页表的大小由进程或作业的长度决定。
例如,对于一个每页长1k,大小为20k的进程来说,如果一个内存单元存放一个页表项,则只要分配给该页表20个存储单元即可。
页式管理是每个进程至少拥有一个页表。
实验中对页表的定义如下(采用数组形式,数组下标表示页号,数组单元存放与数组下标(页号)相应的页面号):int pagetable[100] b.请求表(作业申请表)请求表用来确定作业或进程的虚拟空间的各页在内存中的对应位置。
为了完成这个认为,系统必须知道每个作业或进程的页表起始地址(本实验中假定为0)和长度,以进行内存分配和地址变换。
另外请求表中还包括每个作业或进程所要求的页面数。
请求表整个系统一张,实验中对请求表的定义如下(采用结构体数组形式,并将页表也作为其中一个成员(即域)):# define u 5 struct application_table{char name[8];/*作业名*/int size; /*作业大小――即将上表中的请求页面数改用字节表示*/int paddress; /*页表起始地址*/ int length;/*页表长度――以页面数表示*/int state; /*内存的分配状态,以分配的用1表示,未分配的用0表示*/int pagetable[100];/*页表,放在这里是为了方便虚地址转换及作业撤销的操作*/ }application[u];c.存储页面表(本实验中采用位示图法)位示图也是整个系统一张,它指出内存各页面是否已被分配出去,以及未分配页面的总数。
操作系统_请求分页存储管理模拟实现
操作系统请求分页存储管理模拟实现#include<stdlib.h>#include<iomanip.h>#include"windows.h"#include"os.h"#define n 64//实验中假定主存的长度#define m 4//实验中假定每个作业分得主存块块数int p[m];//定义页struct{short int lnumber;//页号short int flag;//表示该页是否在主存,“1”表示在主存,“0”表示不在主存short int pnumber;//该页所在主存块的块号short int write;//该页是否被修改过,“1”表示修改过,“0”表示没有修改过short int dnumber;//该页存放在磁盘上的位置,即磁盘块号short int times;//被访问的次数,用于LRU算法}page[n];//定义页表//各个函数的实现如下:computer::computer(){int i;for(i=0;i<n;i++){page[i].lnumber = i;page[i].flag = 0;page[i].pnumber = 10000;//用10000表示为空page[i].write = 0;page[i].dnumber = i;page[i].times = 0;}//初始化页表for(i=0;i<m;i++){page[i].pnumber = i;}for(i=0;i<m;i++){p[i] = i;page[i].flag = 1;}//初始化页}void computer::showpagelist(){int i;cout<<"页号"<<"\t"<<"是否在主存中"<<"\t"<<"块号"<<"\t"<<"是否被修改过"<<"\t"<<"磁盘块号"<<"\t"<<"访问次数"<<endl;for(i=0;i<n;i++){cout<<page[i].lnumber<<"\t"<<page[i].flag<<""<<page[i].pnumber<<"\t"<<page[i].write<<" "<<page[i].dnumber<<" \t"<<page[i].times<<endl;}}void computer::showpage(){int i;for(i=0;i<m;i++){cout<<"\t"<<p[i];}cout<<endl;}void computer::transformation(){unsignedlogicAddress,logicNumber,innerAddress,physicsAddress,physicsNumber;int i,head=0,fail = 0;int method,temppage=0;short int times = 10000;cout<<"请输入一个逻辑地址(四位十六进制数):";cin>>hex>>logicAddress;//读入逻辑地址logicNumber = logicAddress >> 10;//得到页号cout<<"页号为:"<<logicNumber<<endl;innerAddress = logicAddress & 0x03ff;//得到页内地址cout<<"页内地址为:"<<innerAddress<<endl;for(i=0;i<n;i++){if(logicNumber==(unsigned)page[i].lnumber){if(page[i].flag == 1){cout<<"请求的页面在主存中!"<<endl;page[i].times++;physicsNumber = page[i].pnumber;//由页号得到块号cout<<"请求的主存块号为:"<<physicsNumber<<endl;physicsAddress = physicsNumber << 10 |innerAddress;//得到物理地址cout<<"请求的物理地址为:"<<physicsAddress<<endl;//输出物理地址break;}else{cout<<"请求的页面不在主存中! 将进行缺页中断处理!"<<endl<<"请选择算法!"<<endl; cout<<"1.先进先出"<<endl<<"2.最近最少用"<<endl<<"请选择置换算法:";cin>>method;if(method == 1) //采用先进先出算法{cout<<"采用先进先出算法!"<<endl;fail = p[head];cout<<"第"<<fail<<"页将被替换!"<<endl;p[head] = logicNumber;head = (head+1) % m;if(page[fail].write == 1)cout<<"第"<<fail<<"页曾被修改过!"<<endl;page[fail].flag = 0;page[logicNumber].flag = 1;page[logicNumber].write = 0;page[logicNumber].pnumber = page[fail].pnumber; page[fail].pnumber = 10000;page[logicNumber].times++;break;}else if(method == 2) //采用最近最少用算法{cout<<"采用最近最少用算法!"<<endl;for(i=0;i<n;i++){if(page[i].flag == 1){if(page[i].times<times){times = page[i].times;temppage = page[i].lnumber;}}}cout<<"第"<<temppage<<"页将被替换!"<<endl; for(i=0;i<m;i++){if(p[i] == temppage){p[i] = logicNumber;}}if(page[temppage].write == 1)cout<<"第"<<temppage<<"页曾被修改过!"<<endl; page[temppage].flag = 0;page[logicNumber].flag = 1;page[logicNumber].write = 0;page[logicNumber].pnumber = page[temppage].pnumber; page[temppage].pnumber = 10000;page[logicNumber].times++;break;}else{ cout<<"你输入有误,即将退出!";exit(1);}}}}}void main(){char c,d;computer os;cout<<"页表正在初始化中...,3秒钟后为你显示页和页表!"<<endl; Sleep(3000);os.showpage();os.showpagelist();T:os.transformation();cout<<"是否显示页和页表?(Y/N)";cin>>c;switch(c){case 'y':os.showpage();os.showpagelist();case 'n':cout<<"是否继续进行请求分页?(Y/N)";cin>>d;if (d=='Y'||d=='y')goto T;else if (d=='N'||d=='n')exit(1);elsecout<<"输入错误!"<<endl; default:cout<<"输入错误!"<<endl; } }。
(完整word版)操作系统实验3--请求分页式存储管理
请求分页式存储管理一、问题描述设计一个请求页式存储管理方案,为简单起见。
页面淘汰算法采用 FIFO 页面淘汰算法,并且在淘汰一页时,只将该页在页表中修改状态位。
而不再判断它是否被改写过,也不将它写回到辅存。
二、基本要求页面尺寸 1K ,输入进程大小(例如 5300bytes),对页表进行初始化页表结构如下:页号物理块号状态位0 2 True (在主存 )1 12 False (在辅存 )3 04 False (在辅存 )5 False (在辅存 )系统为进程分配 3 个物理块(页框),块号分别为 0、1、 2,页框管理表(空闲块表):物理块号是否空闲0 true1 true2 true任意输入一个需要访问的指令地址流(例如:3635、 3642、 1140、 0087、 1700、 5200、4355,输入负数结束),打印页表情况。
每访问一个地址时,首先要计算该地址所在的页的页号,然后查页表,判断该页是否在主存——如果该页已在主存,则打印页表情况;如果该页不在主存且页框未满(查空闲块表,找到空闲块),则调入该页并修改页表,打印页表情况;如果该页不在主存且页框已满,则按 FIFO 页面淘汰算法淘汰一页后调入所需的页,修改页表,打印页表情况。
存储管理算法的流程图见下页。
三、实验要求完成实验内容并写出实验报告,报告应具有以下内容:1、实验目的。
2、实验内容。
3、程序及运行情况。
4、实验过程中出现的问题及解决方法。
#include<stdio.h>#include<stdlib.h>int PUB[20][3];int ABC[3][2]={{0,1},{1,1},{2,1}};//物理块int key=0;void output(int size){//打印int i,j;printf(" 页号 \t\t 物理块号 \t\t 状态位 \n\n");for(i=0;i<size;i++){printf(" %d\t\t%d\t\t\t%d\n\n",PUB[i][0],PUB[i][1],PUB[i][2]);}printf(" 物理块号 \t\t 是否空闲 \n\n");for(i=0;i<3;i++){printf(" %d\t\t\t%d\n\n",ABC[i][0],ABC[i][1]);}}void main(){int size;int i,j;int address=0;int select=0;printf(" 请输入进程大小\n");scanf("%d",&size);if(size<=0 || size>20000){printf(" 进程大小超出范围\n");exit(0);}size%1000==0 ? size=size/1000 : size=size/1000+1;for(i=0;i<size;i++){PUB[i][0]=i;//页号PUB[i][1]=0; //物理块号PUB[i][2]=0; //状态位}output(size);while(1){printf(" 输入指令地址\n");scanf("%d",&address);if(address<0 || address>20000){printf(" 地址超出范围 \n");exit(0);}address%1000==0 ? address=address/1000 : address=address/1000;if(PUB[address][2]==0) //不在主存{if(ABC[2][1]==0)//满了{printf(" 满了 \n");key++;if(select!=address)for(i=0;i<size;i++){if(PUB[i][1]==key){PUB[i][1]=0;PUB[i][2]=0;}}PUB[address][1]=key;PUB[address][2]=1;key++;if(key>3) key=1;}if(ABC[2][1]==1)//没满{printf(" 没满 \n");for(i=0;i<3;i++){if(ABC[i][1]==1){ABC[i][1]=0;PUB[address][1]=i+1;PUB[address][2]=1;break;}}}output(size);}else{printf(" 该页已在内存 \n");output(size);}select=address;}}开始输入进程大小,对页表进行初始化输入要访问的地址0<= 地址 <=进程大小结束是计算页号 , 查页表是该页已是否在主存页框未满是调入该页并修改页表淘汰一页后调入所需的页,修改页表打印页表。
实验报告关于请求调页存储管理方式
《网络操作系统》课程设计报告书题目:请求调页存储管理方式的模拟学号:学生姓名:指导教师:年月日目录一. 实验内容................................................... 错误!未定义书签。
二. 实验目的................................................... 错误!未定义书签。
三. 设计思想................................................... 错误!未定义书签。
四. 程序流程图................................................. 错误!未定义书签。
五. 程序清单................................................... 错误!未定义书签。
六. 运行结果及分析............................................. 错误!未定义书签。
七. 总结....................................................... 错误!未定义书签。
一、实验内容1.假设每个页面中可存放10条指令,分配给作业的内存块数为4。
2.用C语言或C++语言模拟一个作业的执行过程,该作业共有320条指令,即它的地址空间为32页,目前它的所有页都还未调入内存。
在模拟过程中,如果所访问的指令已在内存,则显示其物理地址,并转下一条指令。
如果所访问的指令还未装入内存,则发生缺页,此时需记录缺页的次数,并将相应页调入内存。
如果4个内存块均已装入该作业,则需进行页面置换,最后显示其物理地址,并转下一条指令。
在所有320指令执行完毕后,请计算并显示作业运行过程中发生的缺页率。
3.置换算法:请分别考虑最佳置换算法(OPT)、先进先出(FIFO)算法和最近最久未使用(LRU)算法。
请求调页存储管理方式的模拟
实验3请求调页存储管理方式的模拟1实验目的通过对页面、页表、地址转换和页面置换过程的模拟,加深对请求调页系统的原理和实现过程的理解。
2实验内容(1)假设每个页面中可存放10条指令,分配给一作业的内存块数为4。
(2)模拟一作业的执行过程。
该作业共有320条指令,即它的地址空间为32页,目前它的所有页都还未调入内存。
在模拟过程中,如果所访问的指令已经在内存中,则显示其物理地址,并转下一条指令。
如果所访问的指令还未装入内存,则发生缺页,此时需记录缺页的次数,并将相应页调入内存。
如果4个内存块中均已装入该作业,则需进行页面置换。
最后显示其物理地址,并转下一条指令。
在所有320条指令执行完毕后,请计算并显示作业运行过程中发生的缺页率。
(3)置换算法:请分别考虑OPT、FIFO和LRU算法。
(4)作业中指令的访问次序按下述原则生成:•50%的指令是顺序执行的。
•25%的指令是均匀分布在前地址部分。
•25%的指令时均匀分布在后地址部分。
代码:package mainDart;import java.util.ArrayList;import java.util.List;import java.util.Random;public class FIFO {private static int times=0;//记录置换内存页面的次数/*** 随机产生0~319之间的数* 产生320条指令** @return 包含320条指令的数组*/public static int[] productNumber(){int order[] = new int[320];//数组存储的数字表示指令Random rand = new Random();for(int i=0;i<320;i++){if(i%4==0){order[i]=rand.nextInt(319); //0<=order<319}else if(i%4==1){order[i]=order[i-1]+1;//1<=order<320}else if(i%4==2){order[i]= rand.nextInt(order[i-1]);}else if(i%4==3){order[i]=order[i-1]+rand.nextInt(320-order[i-1]);}}return order;}/*** 打印链表* @param list*/public static void printList(List<Integer> list){for(int temt:list){System.out.print(temt+"\t");}System.out.println();}/*** 先进先出算法* 总是淘汰最先进入内存的页面* 在实现的时候,记录上一次所替换的页面在内存的下标,则本次要替换的位置就是上次下标+1的位置,并且下标是0~3循环的* @param memoryNum* @param page*/public static void FIFOChangePage(List<Integer> memoryNum,int page){int index = FIFOChangePage(memoryNum,page,++times);memoryNum.remove(index);memoryNum.add(index, page);}/*** 返回本次替换的页面在内存中的位置* @param memoryNum* @param page* @param times记录替换页面的次数,第一次替换的是内存第0个单元* @return*/public static int FIFOChangePage(List<Integer> memoryNum,int page,int times) {if(times==1){return 0;}int index = (FIFOChangePage(memoryNum,page,times-1)+1)%4;return index;}public static void main(String[] args) {int[] order = productNumber();System.out.println("320条随机指令数:");for(int i =0;i<order.length;i++){System.out.print(order[i]+"\t");if((i+1)%10==0){System.out.println();}}List<Integer> memoryNum= new ArrayList<Integer>(4);//内存块存储的页面int count=0;//记录缺页次数for(int i=0;i<320;i++){int page = order[i]/10;if(memoryNum.contains(page)) //若该指令所在页面已经在内存,输出该页面所在内存块的号{}else//没在内存,发生缺页,需要判断内存块是否存满,{if(memoryNum.size()<4) //内存没满,直接将所需页面调入内存{memoryNum.add(page);}else//内存存满,需要调用页面置换算法,进行页面置换{FIFOChangePage(memoryNum,page);//先进先出算法}count++;//记录缺页次数}printList(memoryNum);//打印内存所调入页面的情况}System.out.println("缺页率:"+(double)count/320);}}package mainDart;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Random;public class LRU {/*** 随机产生0~319之间的数* 产生320条指令** @return 包含320条指令的数组*/public static int[] productNumber(){int order[] = new int[320];//数组存储的数字表示指令Random rand = new Random();for(int i=0;i<320;i++){if(i%4==0){order[i]=rand.nextInt(319); //0<=order<319}else if(i%4==1){order[i]=order[i-1]+1;//1<=order<320}else if(i%4==2){order[i]= rand.nextInt(order[i-1]);}else if(i%4==3){order[i]=order[i-1]+rand.nextInt(320-order[i-1]);}}return order;}/*** 打印链表* @param list*/public static void printList(List<Integer> list){for(int temt:list){System.out.print(temt+"\t");}System.out.println();}/*** 最近最久未使用算法* @param order*/public static void LRUChangePage(int [] order){List<Integer> memoryNum = new ArrayList<Integer>(4);//内存块int[] timeFlag =new int[]{-1,-1,-1,-1}; //用来记录内存当中各单元未被访问的时间值int count=0;//记录缺页次数for(int i=0;i<320;i++){int page = order[i]/10;if(memoryNum.contains(page)) //若该指令所在页面已经在内存{int index = memoryNum.indexOf(page);timeFlag[index]=0;//将时间变为0 }else//没在内存,发生缺页,需要判断内存块是否存满,{if(memoryNum.size()<4) //内存没满,直接将所需页面调入内存{//将没有命中的所有页面的时间加一for(int in=0;in<4;in++){if(timeFlag[in]!=-1){timeFlag[in]+=1;}}//将page加入内存并将时间置为0memoryNum.add(page);timeFlag[memoryNum.indexOf(page)]=0;}else//内存存满,需要调用页面置换算法,进行页面置换{int maxIn=-1;//记录拥有最大时间值的标记的下标int maxT=-1;//记录最大的时间值for(int in=0;in<4;in++)//找出内存中时间值最大的进行替换{if(timeFlag[in]>maxT){maxT=timeFlag[in];maxIn=in;}}memoryNum.remove(maxIn);memoryNum.add(maxIn,page);timeFlag[maxIn]=0;//将没有命中的所有页面的时间加一for(int in=0;in<4;in++){if(in!=maxIn){timeFlag[in]+=1;}}}count++;//记录缺页次数}printList(memoryNum);//打印内存所调入页面的情况}System.out.println("缺页率:"+(double)count/320);}public static void main(String[] args) {int[] order = productNumber();System.out.println("320条随机指令数:");for(int i =0;i<order.length;i++){System.out.print(order[i]+"\t");if((i+1)%10==0){System.out.println();}}LRUChangePage(order);}}package mainDart;import java.util.ArrayList;import java.util.List;import java.util.Random;public class Optimal {/*** 随机产生0~319之间的数* 产生320条指令** @return 包含320条指令的数组*/public static int[] productNumber(){int order[] = new int[320];//数组存储的数字表示指令Random rand = new Random();for(int i=0;i<320;i++){if(i%4==0){order[i]=rand.nextInt(319); //0<=order<319}else if(i%4==1){order[i]=order[i-1]+1;//1<=order<320}else if(i%4==2){order[i]= rand.nextInt(order[i-1]);}else if(i%4==3){order[i]=order[i-1]+rand.nextInt(320-order[i-1]);}}return order;}/**** @param order320条指令数组* @return 返回一个链表,依次保存着320条指令每条指令所在的页面*/public static List<Integer> pageSeq(int[] order){List<Integer> pageSeq = new ArrayList<Integer>();for(int temp:order){pageSeq.add(temp/10);}return pageSeq;}/*** 打印链表* @param list*/public static void printList(List<Integer> list){for(int temt:list){System.out.print(temt+"\t");}System.out.println();}/*** 最佳置换算法* 根据当前已经在内存中的页面在之后被需要的先后进行置换** @param pageSeq 整个320条指令,从头到尾所需要的页面* @param memoryNum 已满的内存空间* @param page等待被调入内存的页面*/public static void OptimalChangePage(List<Integer> pageSeq,int start,List<Integer> memoryNum,int page){int maxSeq=-1,index=0;for(int pageNum:memoryNum) //遍历内存{for(int i=start;i<pageSeq.size();i++){if(pageNum==pageSeq.get(i)){if(i>maxSeq){maxSeq=i;}break;}}}if(maxSeq>-1)//maxSeq==-1说明内存当中的四个页面在将来都不会再被使用,这时默认将内存块中的第一个页面置换出{index = memoryNum.indexOf(pageSeq.get(maxSeq));//记录将要被置换的那个页面所在内存位置}memoryNum.remove(index);//将内存中将来最久被使用的页面删除memoryNum.add(index, page);//将需要调入的页面加入内存}public static void main(String[] args) {int[] order = productNumber();System.out.println("320条随机指令数:");for(int i =0;i<order.length;i++){System.out.print(order[i]+"\t");if((i+1)%10==0){System.out.println();}}List<Integer> pageSeq = pageSeq(order); //依次存放着指令所在的页面号List<Integer> memoryNum= new ArrayList<Integer>(4);//内存块存储的页面int count=0;//记录缺页次数for(int i=0;i<320;i++){int page = order[i]/10;if(memoryNum.contains(page)) //若该指令所在页面已经在内存,输出该页面所在内存块的号{}else//没在内存,发生缺页,需要判断内存块是否存满,{if(memoryNum.size()<4) //内存没满,直接将所需页面调入内存{memoryNum.add(page);}else//内存存满,需要调用页面置换算法,进行页面置换{OptimalChangePage(pageSeq,i+1,memoryNum,page);//最佳置换算法}count++;//记录缺页次数}printList(memoryNum);//打印内存所调入页面的情况}System.out.println("缺页率:"+(double)count/320);}}package mainDart;import java.util.ArrayList;import java.util.List;public class TestAPP {public static void main(String[] args) {List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(3);list.add(45);System.out.println(list);list.remove(1);list.add(1, -1);System.out.println(list);}}。
存储管理实验1 分页方式内存分配
存储管理实验1 分页存储管理技术中的内存分配(模拟)一、建立一个后备作业队列JCB二、建立一主存分块表M BTMBT 表用于记录各内存块的使用情况。
设内存大小为MS ,块的大小为BS 。
块号(缺省)……三、建立一个作业表JT四、作业调度(为作业分配内存)作业调度算法:按先来先服务算法、优先权或响应比高者优先算法(也可用其它算法) 方法:先判断能否分配,若能,则该作业从后备作业队列中移出。
分配时,随机分配内存块(不一定按照块号顺序分配),并将相应的信息写入MBT 表,产生新的页表。
五、释放内存某号作业运行完毕,释放内存,修改作业表JT、内存分块表MBT,清页表。
六、主程序初始时刻:有若干个作业要求运行,调用建立后备作业队列模块内存分配:循环调用作业调度模块,直到某个作业分配失败而等待时刻二:假设某作业运行完毕,则调用释放内存模块,若后备作业队列不空,则选择一个或几个作业,为其分配内存时刻三,后备作业队列中有新的作业到达,则调用作业分配模块…………时刻X:所有的作业运行完毕七、页式存储管理模拟分配过程举例:作业调度算法——先来先服务(仅供参考,表格及表格中数据请修改并根据需要填满)分配过程:(若块大小为30)块号1234567894号分配失败 2号运行完毕八、说明及要求1.请编制程序,模拟页式存储管理技术中的内存分配过程,打印出源程序及运行结果,要求打印出各个时刻的作业后备队列、MBT表、作业表、各作业的页表、CPU调度表及分配失败等信息。
2.写出实验报告。
实验报告要清晰、具体、独特,有详细中文说明,写明你的程序实现的功能及实现的方法,最好对各变量及数据结构有个说明,给定的变量名不要轻易变动,便于阅读。
3.没有条件打印的可以交盘或发送电子邮件,但在实验报告中最好将主要的数据结构及变量说明写出,并画出流程图。
若能打印,则可以在打印的内容旁作说明。
4.学有余力的学生请设计其它存储管理技术的内存分配的模拟程序,或者将本实验进一步完善。
实验七_模拟虚拟存储器管理
实验七模拟虚拟存储管理一、实验目的在计算机系统中,为了提高主存利用率,往往把辅助存储器(如磁盘)作为主存储器的扩充,使多道运行的作业的全部逻辑地址空间总和可以超出主存的绝对地址空间。
用这种办法扩充的主存储器称为虚拟存储器。
通过本实验帮助理解在分页式存储管理中怎样实现虚拟存储器。
二、实验题目模拟请求分页式虚拟存储管理中硬件的地址转换和缺页中断,以及选择页面调度算法处理缺页中断。
三、背景材料(一)模拟请求分页式存储管理中硬件的地址转换和产生缺页中断。
[提示]请求分页式虚拟存储系统是把作业信息的副本存放在磁盘上,当作业被选中时,可把作业的开始几页先装入主存且启动执行。
为此,在为作业建立页表时,应说明哪些页已在主存,标志----用来表示对应页是否已经装入主存,标志位=1,则表示该页已经在主存,标志位=0,则表示该页尚未装入主存。
主存块号----用来表示已经装入主存的页所占的块号。
在磁盘上的位置----用来指出作业副本的每一页被存放在磁盘上的位置。
1、作业执行时,指令中的逻辑地址指出了参加运算的操作存放的页号和单元号,硬件的地址转换机构按页号查页表,若该页对应标志为“1”,则表示该页已在主存,这时根据关系式:绝对地址=块号×块长+单元号计算出欲访问的主存单元地址。
如果块长为2的幂次,则可把块号作为高地址部分,把单元号作为低地址部分,两者拼接而成绝对地址。
若访问的页对应标志为“0”,则表示该页不在主存,这时硬件发“缺页中断”信号,有操作系统按该页在磁盘上的位置,把该页信息从磁盘读出装入主存后再重新执行这条指令。
2、设计一个“地址转换”程序来模拟硬件的地址转换工作。
当访问的页在主存时,则形成绝对地址,但不去模拟指令的执行,而用输出转换后的地址来代替一条指令的执行。
当访问的页不在主存时,则输出“* 该页页号”,表示产生了一次缺页中断。
该模拟程序的算法如图6-1。
图6-1 地址转换模拟算法3、假定主存的每块长度为128个字节;现有一个共七页的作业,其中第0页至第3页已经装入主存,其余三页尚未装入主存;该作业的页表为:4、运行设计的地址转换程序,显示或打印运行结果。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统模拟实验
实验名称:请求分页存储管理模拟实验
实验目的:通过实验了解windows系统中的线程同步如何使用,进一步了解操作系统的同步机制。
实验内容:调用Windows API,模拟解决生产者-消费者问题;思考在两个线程函数中哪些是临界资源?哪些代码是临界区?哪些代码是进入临界区?哪些代码是退出临界区?进入临界区和退出临界区的代码是否成对出现?学习Windows API中的如何创建线程,互斥,临界区等。
程序运行结果:
源程序:
#include "stdAfx.h"
//包含头文件以支持多线程
#include "windows.h"
#include "stdio.h"
//用于标志所有的子线程是否结束
//每次子线程结束后,此值便加1。
static long ThreadCompleted = 0;
//互斥量
HANDLE mutex;
//信号量,用于生产者通知消费者
HANDLE full;
//信号量,用于消费者通知生产者
HANDLE empty;
//信号量,当所有的子线程结束后,通知主线程,可以结束。
HANDLE evtTerminate;
//生产标志
#define p_item 1
//消费标志
#define c_item 0
//哨兵
#define END 10
//缓冲区最大长度
const int max_buf_size=11;
const int cur_size=10;
//缓冲区定义
int BUFFER[max_buf_size];
//放消息指针
int in=0;
//取消息指针
int out=0;
int front=0;
int tail=0;
int sleep_time=1000;
bool flag=true;
//线程函数的标准格式
unsigned long __stdcall p_Thread(void *theBuf);
unsigned long __stdcall c_Thread(void *theBuf);
//打印缓冲区内容
void PrintBuf(int buf[],int buf_size);
int main(int argc, char* argv[])
{
//初始化缓冲区
unsigned long TID1, TID2;
for(int i=0;i<cur_size;i++)
BUFFER[i]=0;
//互斥量和信号量的创建,函数用法可查看MSDN
mutex=CreateMutex(NULL,false,"mutex");
full=CreateSemaphore(NULL,0,1,"full");
empty=CreateSemaphore(NULL,max_buf_size,max_buf_size,"empty");
evtTerminate = CreateEvent(NULL, FALSE, FALSE, "Terminate");
//创建一个生产者线程和消费者线程。
作为本程序的扩展,你可以增加线程的数目
CreateThread(NULL,0,p_Thread,BUFFER,NULL,&TID1);
CreateThread(NULL,0,c_Thread,BUFFER,NULL,&TID2); while(flag)
{
if(getchar())
{flag=false;}
}
//等待各子线程的结束
WaitForSingleObject(evtTerminate, INFINITE);
return 0;
}
//生产者线程函数
unsigned long __stdcall p_Thread(void *theBuf)
{
while(flag)
{
Sleep(sleep_time);
//可以不要此函数,只是为了模拟缓冲区满的情况
if((front+1)%max_buf_size==tail)
{
printf("缓冲区已满,产品的线程被阻塞\n");
sleep_time+=3000;
}
WaitForSingleObject(empty,INFINITE);//先申请信号量
WaitForSingleObject(mutex,INFINITE);//再申请互斥量
/*进入临界区*/
printf("生产(线程)正在生产请等待\n");
BUFFER[in]=p_item;
in=(in+1)%cur_size;
front=(front+1)%max_buf_size;
PrintBuf(BUFFER,cur_size);
printf("我(生产者线程)已准备退出临界区\n");
//退出临界区
ReleaseMutex(mutex);
ReleaseSemaphore(full,1,0);
}
//线程结束后,将ThreadCompleted值加1
InterlockedIncrement(&ThreadCompleted);
if(ThreadCompleted ==2) SetEvent(evtTerminate);
return 0;
}
//消费者线程函数
unsigned long __stdcall c_Thread(void *theBuf)
{
while(flag)
{
Sleep(3000);
if(front==tail)
{
printf("缓冲区是空的\n");
sleep_time-=3000;
}
//P操作
WaitForSingleObject(full,INFINITE);
WaitForSingleObject(mutex,INFINITE);
printf("一个消费者进入critiction。
\n");
BUFFER[out]=c_item;
out=(out+1)%cur_size;
tail=(tail+1)%max_buf_size;
PrintBuf(BUFFER,cur_size);
printf("消费者已经离开critiction\n");
//V操作
ReleaseMutex(mutex);
ReleaseSemaphore(empty,1,0);
}
//同生产者进程
InterlockedIncrement(&ThreadCompleted);
if(ThreadCompleted ==2) SetEvent(evtTerminate);
return 0;
}
//打印缓冲区
void PrintBuf(int buf[],int buf_size)
{
int i;
printf("当前缓冲区状态:\n");
for(i=0;i<buf_size;i++)
printf("%d,",buf[i]);
printf("\n");
Sleep(1000);
//此函数是为了线程相临两次访问临界区时有序的打印缓冲区内容,//并不是必须的,你可以不要,但模拟的近似度就大打折扣了。
}。