请求分页存储管理模拟实验

合集下载

请求分页实验报告

请求分页实验报告

一、实验目的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-请求分页存储管理模拟实验

操作系统实验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)地址变换机构。

计算机操作系统实验_源码_模拟请求分页虚拟存储管理中的硬件地址变换过程[技巧]

计算机操作系统实验_源码_模拟请求分页虚拟存储管理中的硬件地址变换过程[技巧]
4. 进行缺页中断处理。中断返回后,重新执行该指令。 假定主存的每块长度为64个字节,现有一个具有8页的作业,系统为其分配了4个主存块(即 m=4),且最多分4块。其中第0页至第3页已经装入主存 。该作业的页表如表10—2所示。
地址变换算法框图如图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;
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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);
//此函数是为了线程相临两次访问临界区时有序的打印缓冲区内容,//并不是必须的,你可以不要,但模拟的近似度就大打折扣了。

}。

相关文档
最新文档