西安邮电大学操作系统内存管理实验报告含源码
操作系统存储管理实验报告.doc
操作系统存储管理实验报告实验5存储管理第一,实验的目的1,加深对操作系统存储管理的理解2,可以过度模拟页面调试算法,加深对操作系统内存管理的理解二、一般设计思想、环境语言、工具等一般设计思想:1.编写一个函数来计算和输出以下算法的命中率:(1) OPT页面替换算法OPT选定的过时页面是已经转移到内存中并且将来不会被使用或者在最长时间内不会被访问的页面。
因此,如何找到这样的页面是算法的关键。
每页可以设置一个步长变量。
它的初始值是一个足够大的数字。
对于不在内存中的页面,其值将重置为零。
对于内存中的页面,其值被重置为当前访问的页面与页面首次出现时的距离。
因此,该值越大,在最长时间内不会被访问的页面就越多,并且可以选择它作为交换页面。
(2)先进先出页面替换算法先进先出总是选择首先进入内存的页面进行清除,因此可以设置先进先出的繁忙页面帧队列,新转移到内存的页面挂在队列的尾部,当没有空闲页面帧时,可以从队列的头部取出下一个页面帧作为空闲页面帧,然后再转移到需要的页面。
(3) LRU页面替换算法LRU 根据转移到存储器中的页面的使用做出决定。
它使用“最近的过去”作为“最近的未来”的近似,并选择最长时间没有使用的页面进行删除。
该算法主要通过页面结构中的访问时间来实现。
时间记录页面的最后访问时间。
因此,当需要删除一个页面时,选择时间值最小的页面,即最近最长时间没有使用的页面进行删除。
(4) LFU页面替换算法LFU要求每个页面配置一个计数器(即页面结构中的计数器)。
一旦页面被访问,计数器的值将增加1。
当需要替换一个页面时,将选择计数器值最小的页面,即存储器中访问次数最少的页面进行清除。
⑤NUR页面替换算法NUR要求为每个页面设置一个访问位(访问位仍然可以由页面结构中的计数器表示)。
当页面被访问时,其访问位计数器被设置为1。
当需要页面替换时,替换算法从替换指针(最初指向第一页)开始顺序检查内存中的每一页。
如果其访问位为0,则选择页面进行替换,否则,替换指针向下移动以继续向下搜索。
操作系统-存储管理动态分区分配和恢复算法(带源代码).doc
操作系统-存储管理动态分区分配和恢复算法(带源代码)。
存储管理动态分区分配和恢复算法课程名称:计算机操作系统课程: 信函1501-计算机操作系统类别:信1501:陈丽实验日期:5月XXXX,5月XXXX,5月20日分数: 教师签名:首先,实验目的分区管理是一种广泛使用的存储管理技术。
本实验要求用结构化的高级语言构造分区描述符,编写动态分区分配算法和恢复算法仿真程序,并讨论不同分配算法的特点。
二、实验要求1.写作:首次拟合算法2.写作:最佳拟合算法3.写作:自由区域恢复算法三、实验过程(一)主要程序1.定义分区描述符节点,包括3个元素:(1)adr——分区标题地址(2)大小——分区大小(3)next——指向下一个分区的指针2.定义3个指向节点结构的指针变量:(1)head1——空闲区队列头指针(2)back1——指针指向空闲区节点结构(3)assign——指针指向应用的内存分区节点结构3.定义一个成形变量:免费——用户申请存储区域大小(由用户键入)(2)流程1.定义检查过程以检查指定发布块(由用户键入)的合法性2.定义分配1流程并实施首次拟合算法3.定义分配2过程并实现最佳匹配算法。
4.定义接受1 1流程,并实施首次拟合算法的恢复算法。
5.定义接受2 2过程,实现最佳匹配算法的恢复算法。
6.定义打印过程,打印空闲区队列(3)执行程序首先应用于整个空闲区,第一个地址为0,大小为32767;然后,系统会提示用户使用哪种分配算法,然后是分配还是回收。
分配需要应用程序区域的大小,回收需要释放区域的第一个地址和大小。
CPP # include # include # include # include using命名空间标准;#定义MAX_SIZE 32767typedef结构节点{ int idint adrint大小;结构节点*下一步;}节点;节点*head1,*head2,*back1,*back2,*分配;int请求;内部检查(内部添加、内部大小、字符c){节点*p,*头;int check=1;if(add 0 | | siz next;同时((p!=NULL)检查)如果(((添加:“);sca nf(“% d”,r);if(choosed==' F ' | | choosed==' F ')assign=assign ment 1(num,r);else assign=assignment2(num,r);如果(assign-adr==-1) {printf('未能分配内存!\ n ');Elseprintf('分配成功!分配的内存的第一个地址是:%d\n ',assign-ADR);休息;事例2: printf('输入释放内存的第一个地址:);scanf(“% d”,添加);Printf('输入释放的内存量:);scanf(“% d”,r);Printf('输入释放的内存数量:);scanf(“% d”,rd);if(检查(添加,r,选择)){ if(选择=='f' ||选择=='F') acceptment1(添加,r,rd);else acceptment2(add,r,rd);}休息;case 3:print(已选择);休息;判例4: menu();休息;}}} }}void main()//main函数{ init();菜单();}四.实验结果第五,实验总结通过本实验,我实践了存储管理的动态分区分配和恢复算法,对操作系统中的动态可变分区存储管理有了更深的了解。
操作系统实验报告(2)
操作系统实验报告(2)西安邮电⼤学(计算机学院)课内实验报告实验名称:进程管理专业名称:计算机科学与技术班级:学⽣姓名:学号(8位):指导教师:实验⽇期:*****年**⽉**⽇⼀. 实验⽬的及实验环境⽬的:(1)加深对进程概念的理解,明确进程和程序的区别。
(2)进⼀步认识并发执⾏的实质。
(3)分析进程竞争资源现象,学习解决进程互斥的⽅法。
(4)了解Linux系统中进程通信的基本原理。
环境:Linux操作系统环境:⼆. 实验内容(1)阅读Linux的sched.h源⽂件,加深对进程管理概念的理解。
(2)阅读Linux的fork.c源⽂件,分析进程的创建过程。
三.⽅案设计(1)进程的创建编写⼀段源程序,使系统调⽤fork()创建两个⼦进程,当此程序运⾏时,在系统中有⼀个⽗进程和两个⼦进程活动。
让每⼀个进程在屏幕上显⽰⼀个字符:⽗进程显⽰字符“a”;⼦进程分别显⽰字符“b”和字符“c”。
试观察纪录屏幕上的显⽰结果,并分析原因。
(2)进程的控制修改已编写的程序,将每个进程输出⼀个字符改为每个进程输出⼀句话,在观察程序执⾏时屏幕出现的现象,并分析原因。
如果在程序中使⽤调⽤lockf()来给每⼀个⼦进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。
(3)①编写⼀段程序,使其现实进程的软中断通信。
要求:使⽤系统调⽤fork()创建两个⼦进程,再⽤系统调⽤signal()让⽗进程捕捉键盘上来的中断信号(即按DEL键);当捕捉到中断信号后,⽗进程⽤系统调⽤Kill()向两个⼦进程发出信号,⼦进程捕捉到信号后分别输出下列信息后终⽌:Child Processll is Killed by Parent!Child Processl2 is Killed by Parent!⽗进程等待两个⼦进程终⽌后,输出如下的信息后终⽌Parent Process is Killed!程序流程图如下:②在上⾯的程序中增加语句signal (SIGNAL, SIG-IGN) 和signal (SIGQUIT, SIG-IGN), 观察执⾏结果,并分析原因。
西安邮电大学linux操作系统课程设计ls的编写含源码
西安郵電大學操作系统课程设计报告书院系名称:计算机学院学生姓名:专业名称:软件工程班级:班学号:时间:2015 年4月13 日至2015 年4月24 日1实验目的操作系统是控制和管理计算机硬件和软件资源的虚拟机,其中的文件系统是对软件和设备进行管理的系统,文件系统是操作系统中非常重要的一个模块,它的实现占用了操作系统源码的最大编码量,其好坏也直接影响着用户对操作系统的感受程度。
通过对操作系统课程设计的实践,进一步加深对文件系统的认识和理解,并在此基础上培养学生的工程应用能力。
实验分别从用户态和内核态两个层次实践文件系统的部分功能。
2实验任务2.1 ls实现在linux下编程实现带参数的shell命令ls,ls命令必须支持如下功能。
1.基本要求(1)支持-l 参数;(2)输出结果按字典排序;(3)列出“.”文件,支持-a参数,在没有-a时候不显示隐藏文件;(4)显示记录总数。
2.高级要求(1)支持对给定的目录进行操作,如ls /tmp;(2)输出结果分栏排序,每栏的宽度由这一栏最长的文件名决定,显示的栏数还受终端显示器的宽度影响,每一列尽可能的等宽;(3)正确显示文件特殊属性suid、sgid和sticky,参见联机帮助确保程序能处理各种情况;(4)支持标准的ls支持选项-R,它的功能是递归地列出目录中所有的文件包含子目录中的文件;(5)支持标准的ls支持选项-u,它会显示出文件的最后访问时间,如果用了-u而不用-l,会有什么结果?;(6)当关掉一个文件的读权限,就不能打开这个文件来读。
如果从一个终端登录,打开一个文件,保持文件的打开状态,然后从另外的终端登录,去掉文件的读权限,这时有什么事情会发生?编写一个程序,先用open()打开一个文件,用read()读一些内容,调用sleep()等待20s以后,再读一些内容,从另外的终端,再等待的20s内去掉文件的读权限,这样会有什么结果?。
2.2编写内核模块显示目录或文件的信息。
操作系统存储管理实验报告
操作系统存储管理实验报告一、实验目的本次实验的目的是通过编写一段程序,实现对内存的分配和回收操作,并验证算法的正确性和性能。
二、实验内容1.实现首次适应算法首次适应算法是一种动态分配的内存管理算法,通过从低地址往高地址内存块,找到第一个满足需求的空闲块进行分配。
具体实现过程如下:(1)初始化内存空间,设置内存块的大小和地址范围;(2)编写一个函数,实现内存的分配操作,根据需求大小找到第一个合适的空闲块,并在其前后设置相应的标志位;(3)编写一个函数,实现内存的回收操作,根据释放块的地址,将其前后的标志位进行合并;(4)模拟应用程序的运行,测试内存的分配和回收操作。
2.实现最佳适应算法最佳适应算法是一种动态分配的内存管理算法,通过整个内存空间,找到最小的满足需求的空闲块进行分配。
具体实现过程如下:(1)初始化内存空间,设置内存块的大小和地址范围;(2)编写一个函数,实现内存的分配操作,遍历整个内存空间,找到满足需求且大小最小的空闲块进行分配;(3)编写一个函数,实现内存的回收操作,根据释放块的地址,将其前后的标志位进行合并;(4)模拟应用程序的运行,测试内存的分配和回收操作。
三、实验结果1.首次适应算法经过测试,首次适应算法能够正确地进行内存的分配和回收操作,并且算法的性能良好。
尽管首次适应算法在分配过程中可能会产生碎片,但是由于它从低地址开始,可以在较短的时间内找到满足需求的空闲块。
在实际应用中,首次适应算法被广泛采用。
2.最佳适应算法经过测试,最佳适应算法能够正确地进行内存的分配和回收操作,并且算法的性能较好。
最佳适应算法会整个内存空间,找到大小最小的满足需求的空闲块。
因此,在分配过程中不会产生很多的碎片,但是算法的执行时间较长。
四、实验总结通过本次实验,我们成功地实现了首次适应算法和最佳适应算法,并对算法的正确性和性能进行了验证。
两种算法在内存的分配和回收过程中都表现出良好的性能,可广泛应用于实际场景中。
实验四 操作系统存储管理实验报告
实验四操作系统存储管理实验报告一、实验目的本次操作系统存储管理实验的主要目的是深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握内存分配、回收、地址转换等关键技术,提高对操作系统存储管理机制的认识和应用能力。
二、实验环境操作系统:Windows 10开发工具:Visual Studio 2019三、实验原理1、内存分配方式连续分配:分为单一连续分配和分区式分配(固定分区和动态分区)。
离散分配:分页存储管理、分段存储管理、段页式存储管理。
2、内存回收算法首次适应算法:从内存低地址开始查找,找到第一个满足要求的空闲分区进行分配。
最佳适应算法:选择大小最接近作业需求的空闲分区进行分配。
最坏适应算法:选择最大的空闲分区进行分配。
3、地址转换逻辑地址到物理地址的转换:在分页存储管理中,通过页表实现;在分段存储管理中,通过段表实现。
四、实验内容及步骤1、连续内存分配实验设计一个简单的内存分配程序,模拟固定分区和动态分区两种分配方式。
输入作业的大小和请求分配的分区类型,程序输出分配的结果(成功或失败)以及分配后的内存状态。
2、内存回收实验在上述连续内存分配实验的基础上,添加内存回收功能。
输入要回收的作业号,程序执行回收操作,并输出回收后的内存状态。
3、离散内存分配实验实现分页存储管理的地址转换功能。
输入逻辑地址,程序计算并输出对应的物理地址。
4、存储管理算法比较实验分别使用首次适应算法、最佳适应算法和最坏适应算法进行内存分配和回收操作。
记录不同算法在不同作业序列下的内存利用率和分配时间,比较它们的性能。
五、实验结果与分析1、连续内存分配实验结果固定分区分配方式:在固定分区大小的情况下,对于作业大小小于或等于分区大小的请求能够成功分配,否则分配失败。
内存状态显示清晰,分区的使用和空闲情况一目了然。
动态分区分配方式:能够根据作业的大小动态地分配内存,但容易产生内存碎片。
2、内存回收实验结果成功回收指定作业占用的内存空间,内存状态得到及时更新,空闲分区得到合并,提高了内存的利用率。
操作系统内存管理实验报告
#include <stdio.h>
#include <malloc.h>
t;
int main(void)
{
char *str; /*为字符串申请分配一块内存*/
if ((str = (char *) malloc(10)) == NULL)
根据练习二改编程序如下:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
int main(void)
{
char *str;
/*为字符串申请分配一块内存*/
if ((str = (char *) malloc(20)) == NULL)
{
同组同学学号:
同组同学姓名:
实验日期:交报告日期:
实验(No. 4)题目:编程与调试:内存管理
实验目的及要求:
实验目的:
操作系统的发展使得系统完成了大部分的内存管理工作,对于程序员而言,这些内存管
理的过程是完全透明不可见的。因此,程序员开发时从不关心系统如何为自己分配内存,
而且永远认为系统可以分配给程序所需的内存。在程序开发时,程序员真正需要做的就
printf("String is %s\n Address is %p\n", str, str);
/*重分配刚才申请到的内存空间,申请增大一倍*/
int main(void)
{
char *str;
/*为字符串申请分配一块内存*/
if ((str = (char *) malloc(10)) == NULL)
《操作系统》存储管理实验报告
《操作系统》存储管理实验报告操作系统是计算机系统中最基础、最核心的软件之一,负责管理计算机硬件资源和提供资源的分配与调度。
而存储管理是操作系统中的重要组成部分,它负责管理计算机的内存,包括内存的分配、回收、保护等操作。
本文将针对存储管理进行实验,并撰写实验报告。
本次实验主要涉及以下内容:内存的分配与回收、内存的保护。
实验过程中,我首先根据操作系统的要求,设计了相应的算法用于内存的分配与回收。
并通过编写程序,验证了算法的正确性。
随后,我进一步研究了内存的保护机制,通过设置访问权限位和访问控制表,实现了对内存的合理保护。
在内存的分配与回收方面,我设计了一种简单的算法,首次适应算法。
具体实现如下:首先,将内存分为若干个块,每个块的大小为固定值。
当需要分配内存时,首先遍历内存块列表,找到第一个大小合适的块,将其分配给进程。
当进程终止时,将其占用的内存块回收,以便后续进程使用。
通过编写程序进行测试,结果表明该算法能够正确地进行内存的分配与回收。
在内存的保护方面,我采用了访问权限位和访问控制表的方式进行。
具体实现如下:首先,为每个进程分配一组访问权限位,记录了该进程能够访问的内存区域。
同时,设置一个访问控制表,记录了每个内存块的权限。
当进程访问一些内存块时,首先检查该进程的访问权限位,再与访问控制表中的权限进行比较,以确定该进程是否有权限访问该内存块。
通过编写程序进行测试,证明了该机制能够有效地保护内存。
总结来说,本次实验主要涉及了操作系统中的存储管理部分,包括内存的分配与回收、内存的保护。
通过设计算法和编写程序,我成功地实现了这些功能,并验证了其正确性。
通过本次实验,我进一步加深了对操作系统存储管理的理解,提高了编程和设计的能力。
操作系统内存管理实验报告
操作系统内存管理实验报告操作系统内存管理实验报告引言:操作系统是计算机系统中的核心软件,负责管理计算机系统的各种资源,其中内存管理是操作系统的重要功能之一。
内存管理的目标是有效地管理计算机的内存资源,提高计算机系统的性能和可靠性。
本实验旨在通过设计和实现一个简单的内存管理系统,加深对操作系统内存管理原理的理解,并通过实践来加深对操作系统的认识。
一、实验背景计算机内存是计算机系统中的重要组成部分,它用于存储程序和数据。
在操作系统中,内存被划分为多个不同的区域,每个区域有不同的用途和访问权限。
内存管理的主要任务是为进程分配内存空间,并进行合理的管理和调度,以提高系统的性能和资源利用率。
二、实验目的本实验旨在通过设计和实现一个简单的内存管理系统,加深对操作系统内存管理原理的理解,并通过实践来加深对操作系统的认识。
具体目标包括:1. 设计和实现一个简单的内存分配算法,实现内存的动态分配和回收;2. 实现内存的地址映射机制,实现虚拟地址到物理地址的转换;3. 实现内存保护机制,确保进程之间的内存隔离和安全性;4. 实现内存的页面置换算法,提高内存的利用率和性能。
三、实验设计与实现1. 内存分配算法为了实现内存的动态分配和回收,我们设计了一个简单的内存分配算法。
该算法根据进程的内存需求和剩余内存空间的大小,选择合适的内存块进行分配。
当进程结束或释放内存时,将已使用的内存块标记为空闲状态,以便下次分配。
2. 地址映射机制为了实现虚拟地址到物理地址的转换,我们设计了一个地址映射机制。
该机制使用页表来记录虚拟地址与物理地址的映射关系。
当进程访问内存时,操作系统根据页表将虚拟地址转换为物理地址,并进行内存访问。
3. 内存保护机制为了确保进程之间的内存隔离和安全性,我们实现了一个简单的内存保护机制。
该机制通过设置每个进程的访问权限,限制进程对内存的读写操作。
只有获得相应权限的进程才能访问内存,确保进程之间的数据安全和隔离。
操作系统实验之内存管理实验报告
操作系统实验之内存管理实验报告一、实验目的内存管理是操作系统的核心功能之一,本次实验的主要目的是深入理解操作系统中内存管理的基本原理和机制,通过实际编程和模拟操作,掌握内存分配、回收、地址转换等关键技术,提高对操作系统内存管理的认识和实践能力。
二、实验环境本次实验在 Windows 操作系统下进行,使用 Visual Studio 作为编程环境,编程语言为 C++。
三、实验原理1、内存分配算法常见的内存分配算法有首次适应算法、最佳适应算法和最坏适应算法等。
首次适应算法从内存的起始位置开始查找,找到第一个满足需求的空闲分区进行分配;最佳适应算法则选择大小最接近需求的空闲分区;最坏适应算法选择最大的空闲分区进行分配。
2、内存回收算法当进程结束释放内存时,需要将其占用的内存区域回收至空闲分区链表。
回收过程中需要考虑相邻空闲分区的合并,以减少内存碎片。
3、地址转换在虚拟内存环境下,需要通过页表将逻辑地址转换为物理地址,以实现进程对内存的正确访问。
四、实验内容1、实现简单的内存分配和回收功能设计一个内存管理模块,能够根据指定的分配算法为进程分配内存,并在进程结束时回收内存。
通过模拟多个进程的内存请求和释放,观察内存的使用情况和变化。
2、实现地址转换功能构建一个简单的页式存储管理模型,模拟页表的建立和地址转换过程。
给定逻辑地址,能够正确计算出对应的物理地址。
五、实验步骤1、内存分配和回收功能实现定义内存分区的数据结构,包括起始地址、大小、使用状态等信息。
实现首次适应算法、最佳适应算法和最坏适应算法的函数。
创建空闲分区链表,初始化为整个内存空间。
模拟进程的内存请求,调用相应的分配算法进行内存分配,并更新空闲分区链表。
模拟进程结束,回收内存,处理相邻空闲分区的合并。
2、地址转换功能实现定义页表的数据结构,包括页号、页框号等信息。
给定页面大小和逻辑地址,计算页号和页内偏移。
通过页表查找页框号,结合页内偏移计算出物理地址。
操作系统内存管理实验报告
scanf("%d",&m);
for(i=0;i<N;i++)
{ a[i]=0;
if(P[i].size<m)
continue;
else if(P[i].size==m)
{ P[i].state=1;
l=1; break; }
else
a[i]=P[i].size-m; }
计算机操作系统
实验名称
内存管理
实验过程
一.实验目的
1.了解内存管理的功能
2.掌握进程可变内存管理的几种内存分配与回收算法
3.掌握可变分区算法中空闲分区的合并方法
二.实验内容
实现下列内存分配算法之一:首次适应算法、循环首次适应、最佳分配算法、最坏分配算法
三.实验程序
#include <stdio.h>
printf("动态分区分配算法:");
while(k!=5)
{printf("\n~~~~("\n1、首次适应算法\n2、循环首次适应算法");
printf("\n3、最坏适应算法\n4、最佳适应算法");
printf("\n5、退出\n");
printf("请选择算法:");
实验总结通过看书学习了解了首次适应算法循环首次适应算法最佳分配算法最坏分配算法的区别以及他们各自的优缺点不同的算法给予不同的分配区域他们各自运行的结果也不同这一点在代码上可以看出
实验报告
系别
班级
学号
姓名
时间
地点
操作系统存储管理实验报告
操作系统存储管理实验报告操作系统存储管理实验报告引言:操作系统是计算机系统中的核心软件之一,它负责管理计算机硬件资源和提供用户与计算机之间的接口。
在操作系统中,存储管理是一个重要的子系统,它负责管理计算机的内存资源。
本实验旨在通过实际操作,深入了解操作系统的存储管理机制,并通过实验结果分析其性能和效果。
实验目的:1. 了解操作系统的存储管理机制;2. 掌握存储管理相关的概念和技术;3. 分析不同存储管理策略的优缺点;4. 通过实验验证不同策略的性能和效果。
实验内容:本次实验主要涉及以下几个方面的内容:1. 内存分配:在操作系统中,内存是计算机中的重要资源,它被划分为多个固定大小的块,每个块称为一页。
实验中,我们将学习不同的内存分配算法,如连续分配、离散分配和分页分配,并通过实验验证它们的性能和效果。
2. 内存回收:当某个进程不再需要使用内存时,操作系统需要回收该内存空间,以便其他进程使用。
实验中,我们将学习不同的内存回收算法,如最佳适应算法、最坏适应算法和首次适应算法,并通过实验比较它们的效果。
3. 虚拟内存管理:虚拟内存是一种扩展内存的技术,它将磁盘空间作为辅助存储器,将部分数据存储在磁盘上,以释放内存空间。
实验中,我们将学习虚拟内存的概念和原理,并通过实验验证其性能和效果。
实验结果与分析:通过实验,我们得到了不同存储管理策略的性能数据,并进行了分析。
在内存分配方面,连续分配在内存利用率方面表现较好,但容易产生外部碎片;离散分配能够充分利用内存空间,但需要额外的管理开销;分页分配能够灵活地分配内存,但会带来内部碎片。
在内存回收方面,最佳适应算法能够更好地利用内存空间,但需要较长的搜索时间;最坏适应算法能够减少外部碎片,但可能导致内存利用率较低;首次适应算法在搜索时间和内存利用率方面都有较好的平衡。
在虚拟内存管理方面,虚拟内存能够有效扩展内存空间,提高系统的性能和效率。
通过实验,我们发现虚拟内存的使用可以显著减少交换空间的开销,并提高系统的响应速度。
西安邮电大学操作系统进程实验报告含源码
西安邮电大学(计算机学院)课内实验报告实验名称:进程管理专业名称:软件工程班级:学生姓名:学号(8位):指导教师:***实验日期:2014年11月4日一.实验目的及实验环境(一)、实验环境1. 硬件(1) 主机:Pentium III 以上;(2) 内存:128MB 以上;(3) 显示器:VGA 或更高;(4) 硬盘空间:至少100MB 以上剩余空间。
2. 软件Ubuntu下gcc编译器、gdb调试工具。
(二)、实验目的进程: 1、通过观察、分析实验现象,深入理解多进程并发执行的过程、fork函数在创建子进程时对内存的操作;2、加深对进程概念的理解,明确进程和程序的区别;3、进一步认识并发执行的实质;4、分析进程争用资源的现象,学习解决进程互斥的方;5、了解Linux系统中进程通信的基本原理。
线程:1、理解多线程的概念,学会Linux编程中的线程的创建与终止。
2、理解多线程并发工作时对资源的抢占,通过本实验掌握在Linux操作系统中遵循Posix线程标准接口进行多线程程序编程,熟练掌握线程的创建pthread_create()。
互斥与死锁:1、理解死锁的产生原因与Linux编程中对临界资源进行加锁使得多进程或多线程对临界资源进行互斥访问。
2、利用信号量或者互斥锁实现线程间的同步。
二、实验内容<1>、完成程序填空<2>、回答下列问题进程:1、你最初认为运行结果会怎么样?答:会持续输出0-9号进程,直到输入数字键+回车,则会杀死该进程,接下来的输出将不会有该进程号,当输入q+回车,则退出程序。
2、实际的结果什么样?有什么特点?试对产生该现象的原因进行分析。
答:实际的结果与预期差不多。
因输入进程总数3小于设定的最大进程数,因此按进程数3来处理。
随机输出0-2号进程,sleep(SLEEP_INTERVAL),循环输出,输入数字键,则会杀死该数字对应的进程,直到输入q退出循环,然后kill杀死本组所有进程。
操作系统实验—内存管理源代码
//该程序从文件读入每次的操作,并将结果输出到out.txt文件中#include <stdio.h>#include <stdlib.h>#include <windows.h>#include <iostream.h>#include <fstream.h>struct operation{int time; // 起始时间开始执行的时间int block; //内存页数块数int oper; //操作int protection; //权限};struct trace //跟踪每一次分配活动的数据结构{LPVOID start; //起始地址long size; //分配的大小};HANDLE allo,trac;//信号量句柄DWORD Tracker(LPDWORD lpdwparm) //跟踪allocator线程的内存行为,并输出必要信息{ofstream outfile; //输出文件outfile.open("out.txt");for(int i=0;i<=30;i++){WaitForSingleObject(trac,INFINITE);//等待allocator一次内存分配活动结束//打印内存状况和系统状况outfile<<i<<endl;//以下一段显示系统信息,每次执行操作后系统消息不变//每次的系统信息相同,察看时可以取消注释//系统信息SYSTEM_INFO info;GetSystemInfo(&info);outfile<<"dwActiveProcessorMask"<<'\t'<<info.dwActiveProcessorMask<<endl;outfile<<"dwAllocationGranularity"<<'\t'<<info.dwAllocationGranularity<<endl;outfile<<"dwNumberOfPrecessors"<<'\t'<<info.dwNumberOfProcessors<<endl;outfile<<"dwOemID"<<'\t'<<info.dwOemId<<endl;outfile<<"dwPageSize"<<'\t'<<info.dwPageSize<<endl;outfile<<"dwProcessorType"<<'\t'<<info.dwProcessorType<<endl;outfile<<"lpMaximumApplicationAddress"<<'\t'<<info.lpMaximumApplicationAddress<<endl; outfile<<"lpMinimumApplicationAddress"<<'\t'<<info.lpMinimumApplicationAddress<<endl; outfile<<"wProcessorArchitecture"<<'\t'<<info.wProcessorArchitecture<<endl;outfile<<"wProcessorLevel"<<'\t'<<info.wProcessorLevel<<endl;outfile<<"wProcessorRevision"<<'\t'<<info.wProcessorRevision<<endl;outfile<<"wReserved"<<'\t'<<info.wReserved<<endl;outfile<<"*************************************************"<<endl;//内存状况MEMORYSTATUS status;GlobalMemoryStatus(&status);outfile<<"dwAvailPageFile"<<'\t'<<status.dwAvailPageFile<<endl;outfile<<"dwAvailPhys"<<'\t'<<status.dwAvailPhys<<endl;outfile<<"dwAvailVirtual"<<'\t'<<status.dwAvailVirtual<<endl;outfile<<"dwLength"<<'\t'<<status.dwLength<<endl;outfile<<"dwMemoryLoad"<<'\t'<<status.dwMemoryLoad<<endl;outfile<<"dwTotalPageFile"<<'\t'<<status.dwTotalPageFile<<endl;outfile<<"dwTotalPhy"<<'\t'<<status.dwTotalPhys<<endl;outfile<<"dwTotalVirtual"<<'\t'<<status.dwTotalVirtual<<endl;outfile<<"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&"<<endl;//内存基本信息,每次执行的结果相同,察看时可以取消注释MEMORY_BASIC_INFORMATION mem;VitualQuery(info.lpMinimumApplicationAddress,&mem,sizeof(MEMORY_BASIC_INFORMA TION));outfile<<"AllocationBase"<<'\t'<<mem.AllocationBase<<endl;outfile<<"AllocationProtect"<<'\t'<<mem.AllocationProtect<<endl;outfile<<"BaseAddress"<<'\t'<<mem.BaseAddress<<endl;outfile<<"Protect"<<'\t'<<mem.Protect<<endl;outfile<<"RegionSize"<<'\t'<<mem.RegionSize<<endl;outfile<<"State"<<'\t'<<mem.State<<endl;outfile<<"Type"<<'\t'<<mem.Type<<endl;outfile<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "<<endl;//释放信号量通知allocator可以执行下一次内存分配活动ReleaseSemaphore(allo,1,NULL);}return 0;}void Allocator()//模拟内存分配活动的线程{trace traceArray[5];int index=0;FILE* file;file=fopen("opfile","rb");//读入文件operation op;SYSTEM_INFO info;DWORD temp;GetSystemInfo(&info);for(int i=0;i<30;i++){WaitForSingleObject(allo,INFINITE);//等待tracker打印结束的信号量cout<<i<<':';fread(&op,sizeof(operation),1,file);Sleep(op.time);//执行时间,如果想在指定时间执行可以取消注释GetSystemInfo(&info);switch(op.protection)//根据文件内容确定权限{case 0:{index=0;temp=PAGE_READONLY;break;}case 1:temp=PAGE_READWRITE;break;case 2:temp=PAGE_EXECUTE;break;case 3:temp=PAGE_EXECUTE_READ;break;case 4:temp=PAGE_EXECUTE_READWRITE;break;default:temp=PAGE_READONLY;}switch(op.oper){case 0://保留一个区域{cout<<"reserve now "<<endl;traceArray[index].start=VirtualAlloc(NULL,op.block*info.dwPageSize,MEM_RESERVE,PAGE_NOACCESS);traceArray[index++].size=op.block*info.dwPageSize;cout<<"starting address:"<<traceArray[index-1].start<<'\t'<<"size:"<<traceArray[index-1].size<<endl;break;}case 1://提交一个区域{cout<<"commit now "<<endl;traceArray[index].start=VirtualAlloc(traceArray[index].start,traceArray[index].size,MEM_COMMIT,temp);index++;cout<<"starting address:"<<traceArray[index-1].start<<'\t'<<"size:"<<traceArray[index-1].size<<endl;break;}case 2://锁一个区域{cout<<"lock now"<<endl;cout<<"starting address:"<<traceArray[index].start<<'\t'<<"size:"<<traceArray[index].size<<endl;if(!VirtualLock(traceArray[index].start,traceArray[index++].size))cout<<GetLastError()<<endl;//GetLastError()函数返回错误号break;}case 3://解锁一个区域{cout<<"unlock now"<<endl;cout<<"starting address:"<<traceArray[index].start<<'\t'<<"size:"<<traceArray[index].size<<endl;if(!VirtualUnlock(traceArray[index].start,traceArray[index++].size))cout<<GetLastError()<<endl;break;}case 4://回收一个区域{cout<<"decommit now"<<endl;cout<<"starting address:"<<traceArray[index].start<<'\t'<<"size:"<<traceArray[index].size<<endl;if(!VirtualFree(traceArray[index].start,traceArray[index++].size,MEM_DECOMMIT)) cout<<GetLastError()<<endl;break;}case 5://释放一个区域{cout<<"release now"<<endl;cout<<"starting address:"<<traceArray[index].start<<'\t'<<"size:"<<traceArray[index].size<<endl;if(!VirtualFree(traceArray[index++].start,0,MEM_RELEASE))cout<<GetLastError()<<endl;break;}default:cout<<"error"<<endl;}ReleaseSemaphore(trac,1,NULL);//释放信号量通知tracker可以打印信息}}int main(){DWORD dwThread;HANDLE handle[2];//生成两个线程handle[0]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Tracker,NULL,0, &dwThread);handle[1]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Allocator,NULL,0, &dwThread);//生成两个信号量allo=CreateSemaphore(NULL,0,1,"allo");trac=CreateSemaphore(NULL,1,1,"trac");//等待线程执行的执行结束后,再退出WaitForMultipleObjects(2,handle,TRUE,INFINITE);return 0;}。
操作系统存储管理实验报告
实验五存储管理一、实验目的1 、加深对操作系统存储管理的理解2 、能过模似页面调试算法,加深理解操作系统对内存的高度管理二、总的设计思想、环境语言、工具等总的设计思想:1、编写函数计算并输出下述各种算法的命中率①OPT页面置换算法OPT所选择被淘汰的页面是已调入内存,且在以后永不使用的,或是在最长时间内不再被访问的页面。
因此如何找出这样的页面是该算法的关键。
可为每个页面设置一个步长变量,其初值为一足够大的数,对于不在内存的页面,将其值重置为零,对于位于内存的页面,其值重置为当前访问页面与之后首次出现该页面时两者之间的距离,因此该值越大表示该页是在最长时间内不再被访问的页面,可以选择其作为换出页面。
②FIFO页面置换算法FIFO总是选择最先进入内存的页面予以淘汰,因此可设置一个先进先出的忙页帧队列,新调入内存的页面挂在该队列的尾部,而当无空闲页帧时,可从该队列首部取下一个页帧作为空闲页帧,进而调入所需页面。
③LRU页面置换算法LRU是根据页面调入内存后的使用情况进行决策的,它利用“最近的过去”作为“最近的将来”的近似,选择最近最久未使用的页面予以淘汰。
该算法主要借助于页面结构中的访问时间time来实现,time记录了一个页面上次的访问时间,因此,当须淘汰一个页面时,选择处于内存的页面中其time值最小的页面,即最近最久未使用的页面予以淘汰。
④LFU页面置换算法LFU要求为每个页面配置一个计数器(即页面结构中的counter),一旦某页被访问,则将其计数器的值加1,在需要选择一页置换时,则将选择其计数器值最小的页面,即内存中访问次数最少的页面进行淘汰。
⑤NUR页面置换算法NUR要求为每个页面设置一位访问位(该访问位仍可使用页面结构中的counter 表示),当某页被访问时,其访问位counter置为1。
需要进行页面置换时,置换算法从替换指针开始(初始时指向第一个页面)顺序检查处于内存中的各个页面,如果其访问位为0,就选择该页换出,否则替换指针下移继续向下查找。
内存管理-操作系统实验-代码
实验报告撰写要求实验报告要求具有以下内容:一、实验目的二、实验内容三、实验要求四、算法流程图五、给出测试数据及运行结果六、实验体会或对改进实验的建议操作系统实验课第三次实验及代码实验3 内存管理(2学时)一、实验目的通过实验加强对内存管理方法的理解和掌握。
二、实验内容编写程序实现采用可变分区方法管理内存。
三、实验要求1、在该实验中,采用可变分区方式完成对存储空间的管理(即存储空间的分配与回收工作)。
2、设计用来记录主存使用情况的数据结构:已分区表和空闲分区表或链表。
3、在设计好的数据结构上设计一个主存分配算法。
4、在设计好的数据结构上设计一个主存回收算法。
其中,若回收的分区有上邻空闲分区和(或)下邻空闲分区,要求合并为一个空闲分区登记在空闲分区表的一个表项里。
5、(附加)若需要可以实现程序的浮动,对内存空间进行紧凑。
#include<iostream>#include<vector>#include<fstream>#include<sstream>#include<string>using namespace std;typedef struct node{int ID; //分区IDstruct node *next; //指向下个分区的指针float beginAddress;//分区起始地址float length;//分区长度int ZY;//分区是否被占用,1被占用,0未被占用}FQ;FQ *First=(FQ*)malloc(sizeof(FQ)); //链表的头指针int FQCount=0;//分区的个数void display();//显示内存状态void FenPei(float len);//主存分配函数void HuiShou(int id);//主存回收函数int maxID=0;int main(){//初始化内存分区状态fstream file;file.open("input.txt",ios_base::in|ios_base::out|ios_base::app);string s0;getline(file,s0);istringstream sin(s0);sin>>FQCount;FQ *temp=(FQ*)malloc(sizeof(FQ)); //当前指针temp=First;for(string s;getline(file,s);){FQ *fq=(FQ*)malloc(sizeof(FQ));istringstream sin(s);.sin>>fq->beginAddress;sin>>fq->length;sin>>fq->ZY;fq->ID=++maxID;fq->next=NULL;temp->next=fq;temp=fq;}cout<<"最初的内存分配状态:"<<endl;display();while(1){cout<<"请选择要进行的操作:\n1.请求分配内存 2.请求回收内存 3.退出\n";int choice;cin>>choice;if(choice==1){cout<<"请求分配内存\n";cout<<"请输入要分配的内存的长度:";int len;cin>>len;FenPei(len);}else if(choice==2){cout<<"请求回收内存\n";cout<<"请输入要回收的内存的ID:";int ID;cin>>ID;HuiShou(ID);}else if(choice==3){break;}else{cout<<"输入有误!请重新选择!\n";continue;}}return 1;}void display(){FQ *fqBegin=First->next;cout<<"ID\tBeginAddress\tLength\tState\n";while(fqBegin!=NULL){cout<<fqBegin->ID<<"\t"<<fqBegin->beginAddress<<"\t\t"<<fqBegin->length<<"\t"<<fqB egin->ZY<<endl;fqBegin=fqBegin->next;}}void FenPei(float len){FQ *temp=(FQ*)malloc(sizeof(FQ)); //当前指针temp=First;while(!(temp->next->ZY==0&&temp->next->length>=len)){temp=temp->next;}temp=temp->next;FQ *fq1=(FQ*)malloc(sizeof(FQ));fq1->ID=++maxID;fq1->next=temp->next;fq1->beginAddress=temp->beginAddress+len;fq1->length=temp->length-len;fq1->ZY=0;temp->next=fq1;temp->length=len;temp->ZY=1;display();}void HuiShou(int id){FQ *temp=(FQ*)malloc(sizeof(FQ)); //当前指针temp=First;while(!(temp->next->ID==id)){temp=temp->next;}if(temp->ZY==0){if(temp->next->next==NULL){temp->next=NULL;temp->length=temp->length+temp->next->length;}else if(temp->next->next->ZY==1){temp->next=temp->next->next;temp->length=temp->length+temp->next->length;}else{temp->length=temp->length+temp->next->length+temp->next->next->length;temp->next=temp->next->next->next;}}else{if(temp->next->next==NULL||temp->next->next->ZY==1){temp->next->ZY=0;}else{temp->next->length=temp->next->length+temp->next->next->length;temp->next->next=temp->next->next->next;temp->next->ZY=0;}}display();}0805114实验4 页面置换算法(2学时)(待续敬请期待) 一、实验目的通过实验加强对虚拟存储管理中页面置换算法的理解和掌握。
操作系统实验之内存管理实验报告
int size; int start_addr; struct Free_Block *next; } Free_Block; Free_Block *free_block;
定义已分配的内存空间的结构体,用来保存已经被进程占用了内存空间的情
该模块完成在内存空间中申请一块空间供进程使用的功能,通过输入进程大 小系统先查看内存空间中是否有足够的空间供其进行申请,若无,显示分配失败 相应信息,否则在空闲内存分区块中选择最先的一块进行分配,若内存空间不足 则继续向下查找,空闲内存分区的顺序通过三种算法给出。分配内存时,要指定 进程的首地址和大小,并对内存空闲分区的大小做相应的修改。 2.4 进程终止模块
四、开发工具及主要源代码
1、开发工具
sublimeText3 文本编辑器,采用 g++编译。
2、主要源码
这里只给出最先适应算法的源码,由于三种算法均为对链表进行排序,只是 排序依据的属性不同,结构上几乎相似,在此就不做赘述 /*最先适应算法,按地址的大小由小到达排序*/
void rFirst_Fit() {
current_min_addr = temp->next->start_addr; p = temp; } temp = temp->next; } if (p->next != head->next) { temp = p->next; p->next = p->next->next; temp->next = head->next;
不足之处在于,本次实验中没有实现最坏适应法,分析可能是在在排序的 过程中链表的指针出现了错误,在开始调试阶段只对单一算法进行了调试从而 忽略了这个问题的存在,直到编写本报告的时候才发现种问题。
实验四--操作系统存储管理实验报告
实验四 操作系统存储管理实验报告一、实验目的存储管理的主要功能之一是合理地分配空间。
请求页式管理是一种常用的虚拟存储管理技术。
本实验的目的是通过请求页式管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。
二、实验内容(1) 通过计算不同算法的命中率比较算法的优劣。
同时也考虑了用户内存容量对命中率的影响。
页面失效次数为每次访问相应指令时,该指令所对应的页不在内存中的次数。
在本实验中,假定页面大小为1k ,用户虚存容量为32k ,用户内存容量为4页到32页。
(2) produce_addstream 通过随机数产生一个指令序列,共320条指令。
A 、 指令的地址按下述原则生成:1) 50%的指令是顺序执行的2)25%的指令是均匀分布在前地址部分3) 25%的指令是均匀分布在后地址部分B 、 具体的实施方法是:1)在[0,319]的指令地址之间随机选取一起点m ; 2) 顺序执行一条指令,即执行地址为m+1的指令;3) 在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m ’; 4)顺序执行一条指令,地址为m ’+1的指令 5)在后地址[m ’+2,319]中随机选取一条指令并执行; 6) 重复上述步骤1)~5),直到执行320次指令C 、 将指令序列变换称为页地址流在用户虚存中,按每k 存放10条指令排列虚存地址,即320条指令在虚存中页地址流长度页面失效次数命中率-=1的存放方式为:第0条~第9条指令为第0页(对应虚存地址为[0,9]);第10条~第19条指令为第1页(对应虚存地址为[10,19]);。
第310条~第319条指令为第31页(对应虚存地址为[310,319]);按以上方式,用户指令可组成32页。
(3)计算并输出下属算法在不同内存容量下的命中率。
1)先进先出的算法(FIFO);2)最近最少使用算法(LRU);3)最佳淘汰算法(OPT);4)最少访问页面算法(LFR);其中3)和4)为选择内容三、系统框图五运行结果首先打印出产生的指令信息,第一列为指令序列号,第二列为指令地址,第三列为指令所在的虚页号选择FIFO调度算法,并且内存从3也开始逐渐增加到32页,打印出缺页次数缺页率,命中率选择LRU调度算法,并且内存从3也开始逐渐增加到32页,打印出缺页次数缺页率,命中率选择OPT调度算法,并且内存从3也开始逐渐增加到32页,打印出缺页次数缺页率,命中率六实验程序产生指令流文件produce_addstream.h #ifndef PRODUCE_ADDSTREAM_H #define PRODUCE_ADDSTREAM_H #include<stdio.h>#include<stdlib.h>#include<time.h>#include<iomanip.h>#include<vector>using namespace std;#define random(x) (rand()%x)#define MAX_LENGTH 320struct produce{int num; //指令序号int zhiling; //指令地址int virtualpage; //指令虚页号produce *next;};struct produce*creatlist();void insert(struct produce *first,struct produce *s); //插入一个节点(尾插法)void print(struct produce *first); //打印函数int max(vector<vector<int> >,int );struct produce*creatlist(){srand((int)time(0));struct produce*first=new produce;first->next=NULL;int m=0,m1=0;/*int yanzheng[20]={7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};for (int i=0;i<(MAX_LENGTH/4);i++){struct produce *s0;s0=new produce;s0->num=i*4+0;s0->zhiling=yanzheng[i*4+0];s0->virtualpage=s0->zhiling;insert(first,s0);struct produce *s1;s1=new produce;s1->num=i*4+1;s1->zhiling=yanzheng[i*4+1];s1->virtualpage=s1->zhiling;insert(first,s1);struct produce *s2;s2=new produce;s2->num=i*4+2;s2->zhiling=yanzheng[i*4+2];s2->virtualpage=s2->zhiling;insert(first,s2);struct produce *s3;s3=new produce;s3->num=i*4+3;s3->zhiling=yanzheng[i*4+3];s3->virtualpage=s3->zhiling;insert(first,s3);}//*///*for (int i=0;i<(MAX_LENGTH/4);i++){struct produce *s0;s0=new produce;m=random(MAX_LENGTH);s0->num=i*4+0;s0->zhiling=m+1;s0->virtualpage=s0->zhiling/10;insert(first,s0);m1=random(m+1);struct produce *s1;s1=new produce;s1->num=i*4+1;s1->zhiling=m1;s1->virtualpage=s1->zhiling/10;insert(first,s1);struct produce *s2;s2=new produce;s2->num=i*4+2;s2->zhiling=m1+1;s2->virtualpage=s2->zhiling/10;insert(first,s2);struct produce *s3;s3=new produce;s3->num=i*4+3;s3->zhiling=random(MAX_LENGTH-m1-2)+m1+2;s3->virtualpage=s3->zhiling/10;insert(first,s3);}//*/return first;}void insert(struct produce *first,struct produce *s){struct produce *r=first;struct produce *p;while(r){p=r;r=r->next;}p->next=s;p=s;p->next=NULL;}void print(struct produce *first) //打印函数{struct produce *p;p =first->next;cout<<"随机产生的指令的信息如下"<<endl;cout<<"指令序号"<<"指令地址"<<"指令虚页号"<<endl;while (p){cout<<p->num<<'\t'<<p->zhiling<<setw(14)<<p->virtualpage<<endl;p=p->next;}}int max(vector<vector<int> > page,int Maxpage){int a=0,position=0;for (int i=0;i<Maxpage;i++){if (page[i][1]>a){a=page[i][1];position=i;}}return position;}#endif先来先出调度算法:fifo.h#ifndef FIFO_H#define FIFO_Hvoid fifo(struct produce *first,int Maxpage){vector<int> page(Maxpage);//for (int i=0;i<Maxpage;i++)page[i]=-1;int rear=0;//定义一个变量,指向要被替换的位置int pages;//定义变量保存当前指令的所在的地址int count1=0;//int count2=0;//缺页次数int find=1;struct produce *p=first->next;while (p){pages=p->virtualpage;for(int i=0;i<Maxpage;i++){if (page[i]==-1||count1<Maxpage){page[i]=pages;count1 ++;count2 ++;find =1;break;}else if (page[i]==pages){find =1;break;}find=0;}if (find==0){page[rear]=pages;rear ++;rear=rear%Maxpage;count2 ++;}p=p->next;}cout<<"FIFO调度算法缺页次数缺页率命中率"<<endl;cout<<count2<<setw(25)<<double(count2)/MAX_LENGTH<<setw(10)<<1-dou ble(count2)/MAX_LENGTH<<endl;}#endif FIFO_HLRU调度算法lru.h#ifndef LRU_H#define LRU_H#include<vector>using namespace std;//int max(vector<vector<int> >,int );void lru(struct produce*first,int Maxpage){struct produce*p=first->next;vector<vector<int> > page2(Maxpage, vector<int>(2));int count1=0; //定义内存已经被占用的页数int count2=0; //定义记录缺页次数int equal=0; //定义判断如果当前页数与比较的页数,如果相等则为1,否则为0int place=0; //定义要替换的位置for (int i=0;i<Maxpage;i++){page2[i][0]=-1;page2[i][1]=0;}while (p){if (count1<Maxpage){for (int i=0;i<Maxpage;i++){page2[i][1]=page2[i][1]+1;if (page2[i][0]==-1){page2[i][0]=p->virtualpage;count2++;break;}else if (page2[i][0]==p->virtualpage){page2[i][1] =1;}}count1++;}else{for (int i=0;i<Maxpage;i++){page2[i][1] +=1;if (page2[i][0]==p->virtualpage){equal=1;place=i;break;}}if (equal==1){page2[place][1] =1;equal=0;}else{place = max(page2,Maxpage);page2[place][1]=1;page2[place][0]=p->virtualpage;count2++;}}p=p->next;}cout<<"LRU调度算法缺页次数缺页率命中率"<<endl;cout<<count2<<setw(24)<<double(count2)/MAX_LENGTH<<setw(10)<<1-dou ble(count2)/MAX_LENGTH<<endl;}#endif LRU_HOPT调度算法opt.h#ifndef OPT_H#define OPT_H#include<vector>using namespace std;int search(struct produce*place,int position);void opt(struct produce*first,int Maxpage){struct produce*p =first->next;vector<vector<int> > page3(Maxpage, vector<int>(2));int count1=0; //定义内存已被使用的页数int count2=0; //定义缺页次数int current=0; //定义当前工作位置int equal=0; //定义判断如果当前页数与比较的页数,如果相等则为1,否则为0int place=0; //定义要替换的位置for (int i=0;i<Maxpage;i++){page3[i][0]=-1;page3[i][1]=0;}while (p){//cout<<1111<<endl;if (count1<Maxpage){for (int i=0;i<Maxpage;i++){if (page3[i][0]==-1){page3[i][0]=p->virtualpage;page3[i][1]=search(p,current);count2++;break;}else if (page3[i][0]==p->virtualpage){page3[i][1]=search(p,current);}}count1++;}else{for (int i=0;i<Maxpage;i++){if (page3[i][0]==p->virtualpage){equal=1;place=i;break;}}if (equal==1){page3[place][1] =search(p,current);equal=0;}else{place = max(page3,Maxpage);page3[place][1]=search(p,current);page3[place][0]=p->virtualpage;count2 +=1;}}p=p->next;current +=1;}cout<<"OPT调度算法缺页次数缺页率命中率"<<endl;cout<<count2<<setw(25)<<double(count2)/MAX_LENGTH<<setw(10)<<1-dou ble(count2)/MAX_LENGTH<<endl;}int search(struct produce*place,int position){struct produce*p=place->next;int current=place->virtualpage;int position1=position+1;while(p){if (current==p->virtualpage){return position1;}position1++;p=p->next;}return position1;}#endif主函数控制台ccglmain.cpp#include<iostream.h>#include "produce_addstream.h"#include "fifo.h"#include "lru.h"#include "opt.h"void main(){int S; //定义变量记录用户选择char again; //定义变量用户选择继续还是退出cout<<"开始产生内存指令"<<endl;struct produce *first=creatlist();//产生随机指令cout<<"打印产生的指令信息"<<endl;print(first);//打印产生的指令信息while (1){int Maxpage=3;//定义内存最大页面数cout<<"输入你的选择"<<endl;cout<<"1:FIFO(先进先出)调度算法\n"<<"2:LRU(最近最少使用算法)\n"<<"3:OPT(最佳淘汰算法)\n"<<"4:清屏"<<endl;cin>>S;while(S>4||S<1){cout<<"输入错误重新输入"<<endl;cin>>S;}if (S!=4){while(Maxpage<=32){switch(S){case 1:fifo(first,Maxpage);break;case 2:lru(first,Maxpage);break;case 3:opt(first,Maxpage);break;default:break;}Maxpage++;}cout<<"是否继续调用其他算法?是请按y/Y,否请按其它键"<<endl;cin>>again;if(again=='y'||again=='Y'){continue;}else break;}else system("cls");}}。
《操作系统》存储管理实验报告
____大学____学院实验报告课程名称:计算机操作系统实验名称:存储管理实验实验日期:班级:姓名:学号:仪器编号: XX实验报告要求:1.实验目的 2.实验要求 3.实验步骤 4.程序清单 5.运行情况 6.流程图 7.实验体会1、实验目的?通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解,熟悉虚存管理的各种页面淘汰法。
?通过编写和调试地址转换过程的模拟程序以加强对地址转换过程的了解。
2、实验要求?设计一个固定式分区分配的存储管理方案,并模拟实现分区的分配和回收过程。
可以假定每个作业都是批处理作业,并且不允许动态申请内存。
为实现分区的分配和回收,可以设定一个分区说明表,按照表中的有关信息进行分配,并根据分区的分配和回收情况修改该表。
?设计一个可变式分区分配的存储管理方案,并模拟实现分区的分配和回收过程。
对分区的管理法可以是下面三种算法之一:首次适应算法;最坏适应算法;最佳适应算法。
?编写并调试一个段页式存储管理的地址转换的模拟程序。
首先设计好段表、页表,然后给出若干个有一定代表性的地址,通过查找段表页表后得到转换的地址。
要求打印转换前的地址,相应的段表,页表条款及转换后的地址,以便检查。
3、实验步骤(1)理解实验要求,联系所学知识;(2)根据要求编写调度算法;(3)编写完整的实验代码并在VC++ 6.0环境下编译运行;(4)调试程序直至得出结果。
4、程序清单?#include <stdio.h>#include <stdio.h>#include<math.h>#include<stdlib.h>#define NUM 4#define alloMemory(type) (type*)malloc(sizeof(type))struct partiTab{int no;int size;int firstAddr;char state;}parTab[NUM];typedef struct partiTab PARTITAB;typedef struct jcb { /*定义作业控制块JCB ,部分信息省略*/ char name[10]; //作业名int size; //作业大小struct jcb* link; //链指针}JCB;typedef struct{JCB *front,*rear;}jcbQue;jcbQue *jcbReadyQue;void AllocateMemory(int size);void createTab();void checkTab();void recycleMemory(int i);void AllocateMemory(int size){int i;for(i=0;i<NUM;i++){PARTITAB p=parTab[i];if(p.state='N' && p.size>size)parTab[i].state='Y';elseprintf("没有空闲分区,无法分配内存!\n"); }}void createTab(){int i;for( i=1;i<=NUM;i++){//getPartiTab(PARTITAB);parTab[i-1].no=i;parTab[i-1].size=20;parTab[i-1].firstAddr=21;parTab[i-1].state='N';}}void checkTab(){int i;printf("分区号\t大小\t起址\t状态\n");for(i=0;i<NUM;i++){printf("%d\t",parTab[i].no);printf("%d\t",parTab[i].size); printf("%d\t",parTab[i].firstAddr); printf("%c\t",parTab[i].state); printf("\n");}}void recycleMemory(int i){parTab[i-1].state='N';}int main(int argc, char* argv[]){int i;printf("\n\n\t\t*********************************************\t\t\n");printf("\t\t\t\t实验一存储管理实验\n");printf("\t\t\t\t固定式分区分配存储管理\n");printf("\t\t*********************************************\t\t\n");createTab();checkTab();printf("请按任意键继续:\n");getchar();printf("每个分区装入一道作业:\n");for(i=0;i<NUM;i++){AllocateMemory((i+1)*3);}checkTab();printf("请按任意键继续:\n");getchar();printf("假如一段时间后,其中一个作业结束,回收给它分配的分区(假如该作业在第2分区)\n");recycleMemory(2);checkTab();printf("请按任意键继续:\n");getchar();printf("接着,从外存后备作业队列中选择一个作业装入该分区(假如该作业大小为10)\n");AllocateMemory(10);checkTab();return 0;}?#include<stdio.h>#include <dos.h>#include<stdlib.h>#include<conio.h>#define n 10#define m 10#define minisize 100struct{float address;float length;int flag;}used_table[n];struct{float address;float length;int flag;}free_table[m];void allocate(char J,float xk){int i,k;float ad;k=-1;for(i=0; i<m; i++)if(free_table[i].length>=xk&&free_table[i].flag==1) if(k==-1||free_table[i].length<free_table[k].length) k=i;if(k==-1){printf("无可用空闲区\n");return;}if(free_table[k].length-xk<=minisize){free_table[k].flag=0;ad=free_table[k].address;xk=free_table[k].length;}else{free_table[k].length=free_table[k].length-xk; ad=free_table[k].address+free_table[k].length; }i=0;while(used_table[i].flag!=0&&i<n)i++;if(i>=n){printf("无表目填写已分分区,错误\n");if(free_table[k].flag==0)free_table[k].flag=1;else{free_table[k].length=free_table[k].length+xk; return;}}else{used_table[i].address=ad;used_table[i].length=xk;used_table[i].flag=J;}return;}void reclaim(char J){int i,k,j,s,t;float S,L;s=0;while((used_table[s].flag!=J||used_table[s].flag==0)&&s<n) s++;if(s>=n){printf("找不到该作业\n");return;}used_table[s].flag=0;S=used_table[s].address;L=used_table[s].length;j=-1;k=-1;i=0;while(i<m&&(j==-1||k==-1)){if(free_table[i].flag==1){if(free_table[i].address+free_table[i].length==S)k=i;if(free_table[i].address==S+L)j=i;}i++;}if(k!=-1)if(j!=-1) /* 上邻空闲区,下邻空闲区,三项合并*/{free_table[k].length=free_table[j].length+free_table[k].length+L; free_table[j].flag=0;}else/*上邻空闲区,下邻非空闲区,与上邻合并*/free_table[k].length=free_table[k].length+L;else if(j!=-1) /*上邻非空闲区,下邻为空闲区,与下邻合并*/ {free_table[j].address=S;free_table[j].length=free_table[j].length+L;}else /*上下邻均为非空闲区,回收区域直接填入*/{/*在空闲区表中寻找空栏目*/t=0;while(free_table[t].flag==1&&t<m)t++;if(t>=m) /*空闲区表满,回收空间失败,将已分配表复原*/{printf("主存空闲表没有空间,回收空间失败\n");used_table[s].flag=J;}free_table[t].address=S;free_table[t].length=L;free_table[t].flag=1;}return;}/*主存回收函数结束*/int main( ){printf("\n\n\t\t*********************************************\t\t\n"); printf("\t\t\t\t实验三存储管理实验\n");printf("\n\t\t\t可变式分区分配 (最佳适应算法)\n");printf("\t\t*********************************************\n");int i,a;float xk;/*空闲分区表初始化:*/free_table[0].address=10240; /*起始地址假定为10240*/free_table[0].length=10240; /*长度假定为10240,即10k*/free_table[0].flag=1; /*初始空闲区为一个整体空闲区*/for(i=1; i<m; i++)free_table[i].flag=0; /*其余空闲分区表项未被使用*//*已分配表初始化:*/for(i=0; i<n; i++)used_table[i].flag=0; /*初始时均未分配*/while(1){printf("功能选择项:\n1。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
西安邮电大学(计算机学院)课内实验报告实验名称:内存管理专业名称:软件工程班级:1201班学生姓名:学号(8位):指导教师:实验日期:2014年11月25日一.实验目的及实验环境(一)、实验环境1. 硬件(1) 主机:Pentium III 以上;(2) 内存:128MB 以上;(3) 显示器:VGA 或更高;(4) 硬盘空间:至少100MB 以上剩余空间。
2. 软件Ubuntu下gcc编译器、gdb调试工具。
(二)、实验目的(1)、掌握内存分配FF,BF,WF策略及实现的思路;(2)、掌握内存回收过程及实现思路;(3)、参考本程序思路,实现内存的申请、释放的管理程序,调试运行,总结程序设计中出现的问题并找出原因。
二、实验内容(1)补充完整FF,BF,WF等算法的代码;(2)掌握内存回收过程及实现思路;(3)实现内存的申请和释放。
三.方案设计(一)、实现功能1 - Set memory size (default=1024)2 - Select memory allocation algorithm3 - New process4 - Terminate a process5 - Display memory usage0 - Exit(二)、关键算法思想设计与分析首次适应算法(First Fit):从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。
为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。
该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区。
最佳适应算法(Best Fit):它从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区,这种方法能使碎片尽量小。
为适应此算法,空闲分区表(空闲区链)中的空闲分区要按从小到大进行排序,自表头开始查找到第一个满足要求的自由分区分配。
该算法保留大的空闲区,但造成许多小的空闲区。
最差适应算法(Worst Fit):它从全部空闲区中找出能满足作业要求的、且大小最大的空闲分区,从而使链表中的结点大小趋于均匀,适用于请求分配的内存大小范围较窄的系统。
为适应此算法,空闲分区表(空闲区链)中的空闲分区要按大小从大到小进行排序,自表头开始查找到第一个满足要求的自由分区分配。
该算法保留小的空闲区,尽量减少小的碎片产生。
四.测试数据及运行结果设置内存大小选择算法创建进程选择杀死进程查看内存以及进程五.总结这次实验刚开始的时候不知道整个实验的思路,还好老师在课堂上大概讲解了一下,并且给出了大部分代码,剩下的工作就是填写部分代码,这样实验就简单多了。
通过本次的内存实验我了解到了内存的管理模型的知识,在内存紧缩合并回收部分还遇到了一些问题,最终通过查资料解决了问题,虽然对内存的管理掌握得不是很熟练,但这激励了我下来后看书,努力学习不懂的知识,通过让我对其有了更加深入的了解,让我认识到了,操作系统是一项真正实用,而且很有意义的学科,增加了我对操作系统的兴趣,也为以后的学习打下理论基础。
六、源代码#include<stdio.h>#include<malloc.h>#include<unistd.h>#include<stdlib.h>#define PROCESS_NAME_LEN 32 //进程名长度#define MIN_SLICE 10 //最小碎片的大小#define DEFAULT_MEM_SIZE 1024 //内存大小#define DEFAULT_MEM_START 0 //起始位置/*内存分配算法*/#define MA_FF 1#define MA_BF 2#define MA_WF 3/*描述每一个空闲块的数据结构*/struct free_block_type{int size; //空闲块大小int start_addr; //空闲块起始地址struct free_block_type *next; //指向下一个空闲块};/*指向内存中空闲块链表的首指针*/struct free_block_type *free_block = NULL;/*每个进程分配到的内存块的描述*/struct allocated_block{int pid; //进程标识符int size; //进程大小int start_addr; //进程分配到的内存块的起始地址char process_name[PROCESS_NAME_LEN]; //进程名struct allocated_block *next; //指向下一个进程控制块};/*进程分配内存块链表的首指针*/struct allocated_block *allocated_block_head = NULL;int free_block_count = 0; //空闲块个数int mem_size = DEFAULT_MEM_SIZE; //内存大小int current_free_mem_size = 0; //当前空闲内存大小int ma_algorithm = MA_FF; //当前分配算法static int pid = 0; //初始PIDint flag = 0; //设置内存大小标志,表示内存大小是否设置/*函数声明*/struct free_block_type* init_free_block(int mem_size);void display_menu();int set_mem_size();void set_algorithm();void rearrange(int algorithm);int rearrange_WF();int rearrange_BF();int rearrange_FF();int new_process();int allocate_mem(struct allocated_block *ab);void kill_process();int free_mem(struct allocated_block *ab);int dispose(struct allocated_block *free_ab);int display_mem_usage();struct allocated_block *find_process(int pid);int do_exit();int allocate_FF(struct allocated_block *ab);int allocate_BF(struct allocated_block *ab);int allocate_WF(struct allocated_block *ab);int allocate(struct free_block_type *pre, struct free_block_type *allocate_free_nlock, struct allocated_block *ab);int mem_retrench(struct allocated_block *ab);// 通过内存紧缩技术给新进程分配内存空间int mem_retrench(struct allocated_block *ab){struct allocated_block *allocated_work, *allocated_pre = allocated_block_head;struct free_block_type *free_work, *free_pre = free_block->next;if(allocated_pre == NULL)return -1;allocated_pre->start_addr = 0;allocated_work = allocated_pre->next;while(allocated_work != NULL){allocated_work->start_addr = allocated_pre->start_addr + allocated_pre->size;allocated_pre = allocated_work;allocated_work = allocated_work->next;}free_block->start_addr = allocated_pre->start_addr + allocated_pre->size;free_block->size = current_free_mem_size;free_block->next = NULL;free_work = free_pre;while(free_pre != NULL){free(free_pre);free_pre = free_work;if(free_pre != NULL)free_work = free_work->next;}allocate(NULL, free_block, ab);return 1;}// 给新进程分配内存空间int allocate(struct free_block_type *pre, struct free_block_type *allocate_free_block, struct allocated_block *ab){struct allocated_block *p = allocated_block_head;ab->start_addr = allocate_free_block->start_addr;if(allocate_free_block->size - ab->size < MIN_SLICE){ab->size = allocate_free_block->size;if(pre != NULL){pre->next = allocate_free_block;}else{free_block = allocate_free_block->next;}free(allocate_free_block);}else{allocate_free_block->start_addr += ab->size;allocate_free_block->size -= ab->size;}if(p == NULL){allocated_block_head = ab;}else{while(p->next != NULL)p = p->next;p->next = ab;}current_free_mem_size -= ab->size;if(current_free_mem_size == 0)free_block = NULL;return 0;}//按照最坏适应算法给新进程分配内存空间int allocate_WF(struct allocated_block *ab){int ret;struct free_block_type *wf = free_block;if(wf == NULL)return -1;if(wf->size >= ab->size)allocate(NULL, wf, ab);else if(current_free_mem_size >= ab->size)ret = mem_retrench(ab);elseret = -2;rearrange_WF();return ret;}// 按照最佳适应算法给新进程分配内存空间int allocate_BF(struct allocated_block *ab){int ret;struct free_block_type *pre = NULL, *bf = free_block;if(bf == NULL)return -1;while(bf != NULL){if(bf->size >= ab->size){ret = allocate(pre, bf,ab);break;}pre = bf;pre = pre->next;}if(bf == NULL && current_free_mem_size > ab->size) ret = mem_retrench(ab);elseret = -2;rearrange_BF();return ret;}// 按照首次适应算法给新进程分配内存空间int allocate_FF(struct allocated_block *ab){int ret;struct free_block_type *pre = NULL, *ff = free_block;if(ff == NULL)return -1;while(ff != NULL){if(ff->size >= ab->size){ret = allocate(pre, ff,ab);break;}pre = ff;pre = pre->next;}if(ff == NULL && current_free_mem_size > ab->size) ret = mem_retrench(ab);elseret = -2;rearrange_FF();return ret;}//分配内存模块int allocate_mem(struct allocated_block *ab){int ret ;struct free_block_type *fbt, *pre;int request_size = ab->size;fbt = pre = free_block;switch(ma_algorithm){case MA_FF :ret = allocate_FF(ab);break;case MA_BF :ret = allocate_BF(ab);break;case MA_WF :ret = allocate_WF(ab);break;default :break;}return ret;}// 创建一个新的进程。