基于可重定位分区分配算法的内存管理的设计与实现
基于可重定位分区分配算法的内存管理的设计与实现

组号成绩计算机操作系统课程设计报告题目基于可重定位分区分配算法的内存管理的设计与实现专业:计算机科学与技术班级:学号+:指导教师:2016年12月23 日一.设计目的掌握内存的连续分配方式的各种分配算法二.设计内容基于可重定位分区分配算法的内存管理的设计与实现。
本系统模拟操作系统内存分配算法的实现,实现可重定位分区分配算法,采用PCB定义结构体来表示一个进程,定义了进程的名称和大小,进程内存起始地址和进程状态。
内存分区表采用空闲分区表的形式来模拟实现。
要求定义与算法相关的数据结构,如PCB、空闲分区;在使用可重定位分区分配算法时必须实现紧凑。
三.设计原理可重定位分区分配算法与动态分区分配算法基本上相同,差别仅在于:在这种分配算法中,增加了紧凑功能。
通常,该算法不能找到一个足够大的空闲分区以满足用户需求时,如果所有的小的空闲分区的容量总和大于用户的要求,这是便须对内存进行“紧凑”,将经过“紧凑”后所得到的大空闲分区分配给用户。
如果所有的小空闲分区的容量总和仍小于用户的要求,则返回分配失败信息四.详细设计及编码1.模块分析(1)分配模块这里采用首次适应(FF)算法。
设用户请求的分区大小为u.size,内存中空闲分区大小为m.size,规定的不再切割的剩余空间大小为size。
空闲分区按地址递增的顺序排列;在分配内存时,从空闲分区表第一个表目开始顺序查找,如果m.size≥u.size且m.size-u.size≤size,说明多余部分太小,不再分割,将整个分区分配给请求者;如果m.size≥u.size且m.size-u.size>size,就从该空闲分区中按请求的大小划分出一块内存空间分配给用户,剩余的部分仍留在空闲分区表中;如果m.size<u.size则查找下一个空闲分区表项,直到找到一个足够大的空闲分区;如果没有找到一个足够大的内存空闲分区,但所有的小的空闲分区的容量总和大于用户的要求,就进行紧凑,将紧凑后得到的大的空闲分区按上述的方式分配给用户;但如果所有的小的空闲分区的容量总和仍不能满足用户需要,则分配失败。
基于可重定位分区分配算法的内存管理的设计与实现

组号成绩计算机操作系统课程设计报告题目基于可重定位分区分配算法的内存管理的设计与实现专业:计算机科学与技术班级:学号+XX:指导教师:2016年12月23 日一.设计目的掌握内存的连续分配方式的各种分配算法二.设计内容基于可重定位分区分配算法的内存管理的设计与实现。
本系统模拟操作系统内存分配算法的实现,实现可重定位分区分配算法,采用PCB定义结构体来表示一个进程,定义了进程的名称和大小,进程内存起始地址和进程状态。
内存分区表采用空闲分区表的形式来模拟实现。
要求定义与算法相关的数据结构,如PCB、空闲分区;在使用可重定位分区分配算法时必须实现紧凑。
三.设计原理可重定位分区分配算法与动态分区分配算法基本上相同,差别仅在于:在这种分配算法中,增加了紧凑功能。
通常,该算法不能找到一个足够大的空闲分区以满足用户需求时,如果所有的小的空闲分区的容量总和大于用户的要求,这是便须对内存进行“紧凑”,将经过“紧凑”后所得到的大空闲分区分配给用户。
如果所有的小空闲分区的容量总和仍小于用户的要求,则返回分配失败信息四.详细设计及编码1.模块分析(1)分配模块这里采用首次适应(FF)算法。
设用户请求的分区大小为u.size,内存中空闲分区大小为m.size,规定的不再切割的剩余空间大小为size。
空闲分区按地址递增的顺序排列;在分配内存时,从空闲分区表第一个表目开始顺序查找,如果m.size≥u.size且m.size-u.size≤size,说明多余部分太小,不再分割,将整个分区分配给请求者;如果m.size≥u.size且m.size-u.size>size,就从该空闲分区中按请求的大小划分出一块内存空间分配给用户,剩余的部分仍留在空闲分区表中;如果m.size<u.size则查找下一个空闲分区表项,直到找到一个足够大的空闲分区;如果没有找到一个足够大的内存空闲分区,但所有的小的空闲分区的容量总和大于用户的要求,就进行紧凑,将紧凑后得到的大的空闲分区按上述的方式分配给用户;但如果所有的小的空闲分区的容量总和仍不能满足用户需要,则分配失败。
可变分区存储管理及可重定位分区存储管理实验报告

可变分区存储管理及可重定位分区存储管理实验报告一、实验目的与要求通过消化理解模拟管理程序,了解存储器的分配与回收过程,体会相关数据结构在实现管理算法中的重要性。
输入一到两组实验数据,观察分配与回收的处理结果,特别是回收时邻接空闲分区的合并处理,检测其算法的正确性。
二、算法思想1、可变分区存储管理(1)算法实现a.分配:查空闲分区链表b.回收:考虑邻接合并(2)实验过程:输入操作命令代码a.分配:输入作业号及作业长度(已建立作业不重复建立)b.回收:输入作业号(不存在作业不释放空间)c .可查看空闲链表情况(检测分配、回收正确性)d.可查看作业表情况(检测分配、回收正确性)2、可重定位分区存储管理在前述可变分区存储管理实验基础上修改实现,即遇大作业存在碎片不够分配时进行合并处理。
注:实现拼接(移动,合并):设立按作业地址排列的有序链表,即用静态链表实现(作业表增加静态链仿真指针),在此基础上按地址从小到大顺序依次向前移动(紧凑处理)。
三、算法实现(可重定位分区存储管理)1、修改相关数据结构(1)作业表增加链接仿真指针int next;分量(2)构造有序静态链表(初始化时next均赋值-1)(3)增加静态链首指针Linkp及空闲总容量计数变量size(注:初始化时Linkp=-1,size=n)2、修改分配函数判断新建立作业长度是否小于等于空闲总容量size值。
若无足够大分区,则先进行合并处理后再分配;若有足够大分区,则按可变分区分配算法处理;若作业长度超过总空闲容量,则产生溢出(无内存)。
3、增加插入排序操作函数(sort_tab())分配新作业空间,则按新作业分区首地址大小,将作业表表项插入静态链表。
回收时,还必须从中删除。
4、增加拼接(移动)操作函数(compact())主要是修改作业表表目内容及空闲分区链表,用模拟操作函数move()进行模拟搬家前移。
5、增加显示静态链表内容的较出操作函数(printsorttab())四、算法流程1、可变分区存储管理(1)主程序(main()函数)(2)分配程序(allocm()函数)(3)回收程序(freem()函数)(4)显示空闲分区链表及作业表程序(printlink()及printtab()函数)注:主程序(main()函数)分配程序(allocm()函数)回收程序(freem()函数)有四种情形(假定回收区首地址=> addr,长度=> length)(1)空闲分区链表空,或不与任何空闲区邻接=> 分配新结点空间,存入回收作业首地址及长度插入空闲分区链(链首,链中,链尾)(2)回收分区与后一空闲分区相邻接=> 进行后邻接合并(3)回首分区与前一空闲分区相邻接(4)回收分区与前同时又与后空闲分区相邻接=> 需进行三个分区合并,并删除一个空闲分区结点注:除了修改空闲分区链表,还要修改作业表(清除flag标志)2、可重定位分区存储管理(1)分配程序(修改allocm()函数)(2)回收程序(修改freem()函数)(3)有序静态链表插入操作程序(sort_tab()函数)(4)拼接(移动)操作程序(compact()函数)(5)输出有序静态链表操作程序(printsorttab()函数)注:分配程序(修改allocm()函数)n,l输出作业已建立提示串,返回内存容量不够,返回置新作业作业表作业地址(分配空间)提示操作者输入新建作业的作业号及长度作业n已建立?l≤size?NYNY分配作业表表项,填入作业长度,置标志为1,总空闲容量减去l查空闲分区链表查到表尾?调用拼接操作函数compact()进行拼接处理Y分区大小=lNYN分区大小>lY修改空闲分区链表(size= l,空闲链为空(一起分配),size> l ,分割分配)作业表表目插入有序静态链表返回切割分配分区空间,修改分区链表作业表表目插入有序静态链表分区整体分配,修改分区链(删除结点)作业表表目插入有序静态链表返回查下一分区N回收程序(修改freem()函数)有序静态链表插入操作程序(sort_tab())拼接(移动)操作程序(compact())五、实验步骤1、可变分区存储管理(1)消化实验算法程序(2)组织上机实验数据(3)第一组:指定(4)第二组:自定(要求能测试各种情形)(5)输入上机程序,编译,运行,记录各操作步骤的运行结果(通过显示空闲分区链表及作业表)2、可重定位分区存储管理(1)阅读相关算法程序(2)组织调试数据(必须包含需合并的操作)(3)上机运行、调试(测试),记录运行情况,分析运行结果六、实验运行情况分析1、可变分区存储管理(1)操作程序1a.分配作业1(80k),作业3(30k),作业8(50k),作业5(140k),作业9(50k),作业6(100k),作业4(50k)b.观察(记录)空闲表及作业表情况c.回收作业8,观察结果d.分配作业7(80k),观察结果e.回收作业6, 回收作业1, 观察结果f分配作业10(120k),观察运行情况g,回收作业7,作业3,作业5,观察各次结果(2)操作程序2a.分配作业1(100k)、作业2(50k)、作业3(50k)、作业4(80k)、作业5(120k),观察结果b.回收作业4c.分配作业6(90k)d.回收作业3 f.分配作业7(140k)2、可重定位分区存储管理(1)操作程序1a.分配作业1(80k),作业3(30k),作业8(50k),作业5(140k),作业9(50k),作业6(100k),作业4(50k)b.观察(记录)空闲表及作业表情况c.回收作业8,观察结果d.分配作业7(80k),观察结果e.回收作业6, 回收作业1, 观察结果f 分配作业10(120k ),观察运行情况g,回收作业7,作业3,作业5,观察各次结果(2)操作程序2a.分配作业1(100k)、作业2(50k)、作业3(50k)、作业4(80k)、作业5(120k),观察结果b.回收作业4c.分配作业6(90k)d.回收作业3 f.分配作业7(140k )七、实验总结通过这次实验,我掌握了可变分区存储管理及可重定位分区存储管理的具体方法,对书本上的理论知识有了更深刻的认识。
操作系统实验任务书(3)-内存管理-可变分区

沈阳工程学院
学生实验任务书
实验室名称:计算机实验室实验课程名称:操作系统
实验项目名称:存储管理(1)
一.实验目的
通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解,熟悉可变分区存储管理的内存分配和回收。
二.实验设备
PC机一台,WIN-TC软件。
三.实验项目
编写程序实现采用可变分区方法管理内存。
1、在该实验中,采用可变分区方式完成对存储空间的管理(即存储空间的分配与回收工作)。
2、设计用来记录主存使用情况的数据结构:已分区表和空闲分区表或链表。
3、在设计好的数据结构上设计一个主存分配算法。
4、在设计好的数据结构上设计一个主存回收算法。
其中,若回收的分区有上邻空闲分区和(或)下邻空闲分区,要求合并为一个空闲分区登记在空闲分区表的一个表项里。
5、(附加)若需要可以实现程序的浮动,对内存空间进行紧凑。
·1·。
电大操作系统判断题

AB 并发是并行的不同表述,其原理相同。
(X)把内存物理地址转变为逻辑地址的过程称作重定位。
(X)C 操作系统是用户与计算机之间的接口。
(√)操作系统是系统软件中的一种,在进行系统安装时可以先安装其它软件,然后再安装操作系统。
(X)操作系统核心提供了大量的服务,其最高层是系统调用,它允许正在运行的程序直接得到操作系统的服务。
(√)操作系统是整个计算机系统的控制管理中心,它对其它软件具有支配权利。
因而,操作系统建立在其它软件之上。
(X)操作系统核心提供了大量的服务,其最高层是系统调用,它允许正在运行的程序直接得到操作系统的服务。
(√)操作系统在组织物理文件时根据存储介质的特性和用户选择的存取方法来决定存储结构。
(√)程序在运行时需要很多系统资源,如内存、文件、设备等,因此操作系统以程序为单位分配系统资源。
(X)处于后备状态的作业已经调入内存中。
(X)处理机调度的主要目的就是为了分配处理机。
(√)处理机调度可分为三级:高级、中级和低级。
在所有的系统中,都必须具备这三级调度。
(×)采用动态重定位技术的系统,目标程序可以不经任何改动,而装入物理内存。
(√)采用了二级目录结构后,可以允许不同用户在为各自的文件命名时,不必考虑重名问题,即使取了相同的名字也不会出错。
(√)采用SPOOLing技术情况下,可用1台计算机代替脱机技术需要的3台计算机。
(√)CPU可以直接访问外存(如磁盘)上的数据。
(X )D 动态优先级算法允许进程的优先级在运行期间不断改变。
(√)动态存储分配时,不需要靠硬件地址变换机构实现重定位。
(X)动态存储分配时,要靠硬件地址变换机构实现重定位。
(√)当进程请求在主存和外设之间传送信息时,设备分配程序分配设备的过程通常是先分配通道,再分配控制器,最后分配设备。
(X)EF 凡是数据到达速率和离去速率不同的地方都可以设置缓冲区。
(√)G 固定分区存储管理的各分区的大小不可变化,这种管理方式不适合多道程序设计系统。
操作系统原理考试题含答案2

操作系统原理考试题含答案21、在一个可变式分区管理中,最坏适应分配算法宜将空闲区表中的空闲区按___________的次序排列。
A、地址递增B、地址递减C、大小递增D、大小递减正确答案: D2、在请求页式存储管理中,若所需页面不在内存中,则会引起 ( )。
A、输入输出中断B、时钟中断C、越界中断D、缺页中断正确答案: D3、()是I/O进程与设备控制器之间的通信程序A、中断处理程序B、设备驱动程序C、设备独立性软件D、用户层软件正确答案: B4、磁盘调度主要是为了优化( )(1.0)A、寻道时间B、旋转延迟时间C、传输时间D、寻找磁盘的时间正确答案: A5、衡量系统的调度性能主要是指标是( )A、作业的周转时间B、作业的输入输出时间C、作业的等待时间D、作业的响应时间正确答案: A6、下列进程调度算法中,____可能会出现进程长期得不到调度的情况。
A、静态优先权法B、抢占式调度中采用动态优先权算法C、分时处理中的时间片轮转调度算法D、非抢占式调度中采用FCFS算法正确答案: A7、在虚拟页式存储管理方案中,当查找的页面不在( )时,会产生缺页中断。
A、外存B、虚存C、内存D、地址空间正确答案: C8、Windows 95是( )操作系统。
A、多用户分时B、批处理系统C、单用户多任务D、单用户单任务正确答案: C9、若系统 S1 采用死锁避免方法,S2 采用死锁检测方法,下列叙述中正确的是( ) Ⅰ.S1 会限制用户申请资源的顺序Ⅱ.S1 需要进行所需资源总量信息,而 S2 不需要Ⅲ.S1 不会给可能导致死锁的进程分配资源,S2 会A、仅ⅠⅡB、仅ⅡⅢC、仅ⅠⅢD、ⅠⅡⅢ正确答案: B10、可重定位内存分区分配目的为____。
A、回收空白区方便B、摆脱用户干预C、便于多作业共享内存D、解决碎片问题正确答案: A11、多道程序的实质是( )A、程序的顺序执行B、程序的并发执行C、多个处理机同时执行D、用户程序和系统正确答案: B12、为了允许不同用户的文件具有相同的文件名,通常在文件系统中采用()A、单级目录B、多级目录C、文件名D、重名翻译正确答案: B13、操作系统中,进程的最基本的特征是________。
电大计算机本科《操作系统》作业及答案

《操作系统》课程作业(四)姓名班级学号一、选择题(选择一个正确答案的代码填入括号中)1.通常,用户编写的程序中所使用的地址是()。
A.逻辑地址 B.物理地址2.3.4.5.6.调入其他所需数据,称为()。
A.覆盖技术B.对换技术C.虚拟技术D.物理扩充7.分区管理中进行分区的是主存的()。
A.系统区域 B.用户区域C.程序区域 D.整个区域8.分区管理要求对每一个作业都分配()的内存单元。
A.地址连续B.若干地址不连续C.若干连续的页面D.若干不连续的页面9.固定分区中各分区的大小是()。
A.相同的 B.相同或者不同,但预先固定10.11.12.A.绝对地址=界限寄存器值+逻辑地址B.绝对地址=下限寄存器值+逻辑地址C.绝对地址=基址寄存器值+逻辑地址D.绝对地址=块号 块长+页内地址13.最先适应分配算法把空闲区()A.按地址顺序从小到大登记在空闲区表中B.按地址顺序从大到小登记在空闲区表中C.按长度以递增顺序登记在空闲区表中D.按长度以递减顺序登记在空闲区表中14.最容易形成很多小碎片的可变分区算法是()。
A.最先适应算法 B.最佳适应算法C.位示图法 D.以上都不是15.16.17.18.19.虚拟存储器的容量是由计算机的地址结构决定的,若CPU有32位地址,则它的虚拟地址空间为()。
A.100K B.640K C.2G D.4G20.在请求分页虚拟存储管理中,若所需页面不在内存中,则会引起()。
A.输入输出中断 B.时钟中断C.越界中断 D.缺页中断21.下列存储管理方案中,不要求将进程全部调入并且也不要求连续存储空间的是()。
A.固定分区 B.可变分区C.页式存储管理 D.请求分页式存储管理22.存储管理中,页面抖动是指()。
23.1.2.3.固定分区存储管理的各分区的大小不可变化,这种管理方式不适合多道程序设计系统。
()4.可重定位分区存储管理可以对作业分配不连续的内存单元。
()5.采用动态重定位技术的系统,目标程序可以不经任何改动,而装入物理内存。
4.10 可重定位分区分配

多重分区分配
6.分区的保护
为了防止一个作业有意或无意地破坏操作系统或其它作 业。一般说来,没有硬件支持,实现有效的存储保护是困难的。 通常采取: 界限寄存器方式
保护键方式
两种措施,或二者兼而有之。
保护过程----防止地址越界
一般由硬件提供一对寄存器: 基址寄存器:存放起始地址 限长寄存器:存放长度 (上界寄存器/下界寄存器)
CH4.10 可重定位分区分配
4.10 可重定位分区分配
1. 动态重定位的引入
图 4-3-1 紧凑的示意
2. 动态重定位的实现
图 4-3-2 动态重定位示意图
3. 动态重定位分区分配算法
图 4-3-3 动态分区分配算法流程图
4.可重定位分区的优缺点
优点:解决了可变分区分配所引入的“外零头” 问题。消
1)界限寄存器保护
如果60K > 访问地址 访问地址 > =124K则产生 访问地址界中断
2)基址、限长寄存器保护
如果相对地址 > 限长寄存器的值则产生访问 地址界中断
防止操作越权
对于允许多个进程共享的存储区域,每个进程都有
自己的访问权限。如果一个进程对共享区域的访问违反
了权限规定,则发生操作越权,即读写保护。
除内存碎片,提高内存利用率。
缺点:提高硬件成本,紧凑时花费CPU时间。
5.多重分区
以上讨论都是基于一个作业在主存中占据的是一个连续
分区的假定。
为了支持结构化程序设计,操作系统往往把一道作业分 成若干片段如子程序、主程序、数据组等)。这样,片段之 间就不需要连续了。 只要增加一些重定位寄存器,就可以有效地控制一道作 业片段之间的调用。 如下图作业A、B分别被分成两个片段放进互不相连的 区域中。由两个变址寄存器实现控制。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
组号成绩计算机操作系统课程设计报告题目基于可重定位分区分配算法的存管理的设计与实现专业:计算机科学与技术班级:学号+:指导教师:2016年12月 23 日一.设计目的掌握存的连续分配方式的各种分配算法二.设计容基于可重定位分区分配算法的存管理的设计与实现。
本系统模拟操作系统存分配算法的实现,实现可重定位分区分配算法,采用PCB定义结构体来表示一个进程,定义了进程的名称和大小,进程存起始地址和进程状态。
存分区表采用空闲分区表的形式来模拟实现。
要求定义与算法相关的数据结构,如PCB、空闲分区;在使用可重定位分区分配算法时必须实现紧凑。
三.设计原理可重定位分区分配算法与动态分区分配算法基本上相同,差别仅在于:在这种分配算法中,增加了紧凑功能。
通常,该算法不能找到一个足够大的空闲分区以满足用户需求时,如果所有的小的空闲分区的容量总和大于用户的要求,这是便须对存进行“紧凑”,将经过“紧凑”后所得到的大空闲分区分配给用户。
如果所有的小空闲分区的容量总和仍小于用户的要求,则返回分配失败信息四.详细设计及编码1.模块分析(1)分配模块这里采用首次适应(FF)算法。
设用户请求的分区大小为u.size,存中空闲分区大小为m.size,规定的不再切割的剩余空间大小为size。
空闲分区按地址递增的顺序排列;在分配存时,从空闲分区表第一个表目开始顺序查找,如果m.size≥u.size且m.size-u.size≤size,说明多余部分太小,不再分割,将整个分区分配给请求者;如果m.size≥u.size且m.size-u.size>size,就从该空闲分区中按请求的大小划分出一块存空间分配给用户,剩余的部分仍留在空闲分区表中;如果m.size<u.size则查找下一个空闲分区表项,直到找到一个足够大的空闲分区;如果没有找到一个足够大的存空闲分区,但所有的小的空闲分区的容量总和大于用户的要求,就进行紧凑,将紧凑后得到的大的空闲分区按上述的方式分配给用户;但如果所有的小的空闲分区的容量总和仍不能满足用户需要,则分配失败。
(2)存回收模块进行存回收操作时,先随机产生一个要回收的进程的进程号,把该进程从进程表中中删除,它所释放的空闲存空间插入到空闲分区表;如果回收区与插入点的前一个空闲分区相邻,应将回收区与插入点的前一分区合并,修改前一个分区的大小;如果回收区与插入点的后一个空闲分区相邻,应将回收区与插入点的后一分区合并,回收区的首址作为新空闲分区的首址,大小为二者之和;如果回收区同时与插入点的前、后空闲分区相邻,应将三个分区合并,使用前一个分区的首址,取消后一个分区,大小为三者之和。
(3)紧凑模块将存中所有作业进行移动,使他们全都相邻接,把原来分散的多个空闲小分区拼接成一个大分区。
2.流程图否否是是3.代码实现#include<stdio.h>#include<stdlib.h>#include<time.h>#include<windows.h>#define TURE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2#define SIZE 15////////////////////////////进程表////////////// int ppNo=1; //用于递增生成进程号int pLength=0;struct PCB{int pNo; //进程号(名)int pSize; // 进程大小int pOccupy; // 实际占用的存int pStartAddr; // 进程起始地址int pState; //进程状态};struct PCB pList[200];//////////////////空闲分区表部分/////////////// typedef int Status;typedef struct emptyNode{ //空闲分区结构体int areaSize; //空闲分区大小int aStartAddr; //空闲分区始址struct emptyNode *next;}emptyNode,*LinkList;int ListDelete(struct PCB *pList,int i);//AAA/删除下标为i的进程void pSort(struct PCB *pList); //AAA/存中的进程按始址递增排序void compact(LinkList &L,struct PCB *pList);//AAA/紧凑 ,存中进程移动,修改进程数据结构;空闲分区合并,修改空闲分区表数据结构void amalgamate(LinkList &L); //AAA/回收后进行合并空闲分区void recycle(LinkList &L,struct PCB *pList); //AAA/回收,从进程表中删除进程,把释放出的空间插入到空闲分区链表中Status InitList(LinkList &L); //1AAA/构造一个新的有头节点的空链表LStatus ClearList(LinkList &L); //2AAA/将链表L重置为空表Status ListInsert(LinkList &L,LinkList s1); //AAA/*****根据始址进行插入void DeleteElem(LinkList &L,int aStartAddr);//*****删除线性表中始址值为aStartAddr的结点void PrintList(LinkList L); //AAA/*****输出各结点的值void creatP(struct PCB *p); //AAA/初始化进程int search(LinkList &L,int pSize); //AAA/检索分区表 ,返回合适分区的首址int add(LinkList &L); //AAA/返回空闲分区总和void pListPrint(struct PCB *pList); //AAA/输出存中空间占用情况void distribute(LinkList &L,struct PCB *process);int ListDelete(struct PCB *pList,int i)//AAA/删除下标为i的进程{for(;i<pLength-1;i++){pList[i]=pList[i+1];}pLength--;}//ListDeletevoid pSort(struct PCB *pList){ //AAA/存中的进程按始址递增排序int i,j;struct PCB temp;for(i=0;i<pLength-1;i++){for(j=0;j<pLength-i-1;j++){if(pList[j].pStartAddr>pList[j+1].pStartAddr){temp=pList[j];pList[j]=pList[j+1];pList[j+1]=temp;}}}}//AAA/紧凑 ,存中进程移动,修改进程数据结构;空闲分区合并,修改空闲分区表数据结构void compact(LinkList &L,struct PCB *pList){printf("进行紧凑\n");//1、进程移动,修改进程数据结构int i;pList[0].pStartAddr=0; //第一个进程移到最上面for(i=0;i<pLength-1;i++){pList[i+1].pStartAddr=pList[i].pStartAddr+pList[i].pOccupy;}//2、空闲分区合并,修改空闲分区表数据结构LinkList p=L->next,s;int sumEmpty=0;while(p!=NULL)//求空闲区总和{sumEmpty+=p->areaSize;p=p->next;}ClearList(L); //清空空闲分区表s=(LinkList)malloc(sizeof(emptyNode));s->aStartAddr=pList[pLength-1].pStartAddr+pList[pLength-1].pOccupy;s->areaSize=sumEmpty;ListInsert(L,s);printf("\n紧凑后的>>>>\n");pListPrint(pList);PrintList(L);}void amalgamate(LinkList &L){//AAA/回收后进行合并空闲分区LinkList p=L->next,q=p->next;while(q!=NULL){if(p->aStartAddr+p->areaSize==q->aStartAddr){p->areaSize+=q->areaSize;DeleteElem(L,q->aStartAddr);//删除被合并的结点q=p->next;}else{p=q;q=q->next;}}}//AAA/回收,从进程表中删除进程,把释放出的空间插入到空闲分区链表中void recycle(LinkList &L,struct PCB *pList){int index,delPNo,delPSize,delPOccupy,delPStartAddr;LinkList s;srand(time(0));index=rand()%pLength;delPNo=pList[index].pNo;delPSize=pList[index].pSize;delPOccupy=pList[index].pOccupy;delPStartAddr=pList[index].pStartAddr;printf("___________________________________________________________________ _____________");printf("回收存进程 P%d: 始址:%d K 占用:%dKB\n",delPNo,delPStartAddr,delPOccupy);printf("\n回收后>>>>\n");ListDelete(pList,index);//pListPrint(pList);s=(LinkList)malloc(sizeof(emptyNode));s->areaSize=delPOccupy;s->aStartAddr=delPStartAddr;ListInsert(L,s);amalgamate(L);pListPrint(pList);//输出存中空间占用情况PrintList(L);}///////////////////////////////////////////Status InitList(LinkList &L) //1AAA/构造一个新的有头节点的空链表L {LinkList s;L=(LinkList)malloc(sizeof(emptyNode)); //生成新节点(头结点)if(!L) return ERROR; //申请存失败s=(LinkList)malloc(sizeof(emptyNode));s->areaSize=900;s->aStartAddr=0;L->next=s; //头节点的指针域指向第一个结点s->next=NULL;return OK;}//InitListStatus ClearList(LinkList &L) //2AAA/将链表L重置为空表{LinkList p,r;p=L->next; r=p->next;while(p!=NULL){free(p);if(r==NULL){p=NULL;}else{p=r;r=p->next;}}L->next=NULL;return OK;}//ClearList//AAA/*****根据始址进行插入Status ListInsert(LinkList &L,LinkList s1) {LinkList r=L,p=L->next,s;//指针s=(LinkList)malloc(sizeof(emptyNode));s->areaSize=s1->areaSize;s->aStartAddr=s1->aStartAddr;if(p==NULL){L->next=s;s->next=NULL;}else{while(p!=NULL){if(s1->aStartAddr < p->aStartAddr){s->next=r->next;r->next=s;break;}r=p;p=p->next; //后移}if(p==NULL){r->next=s;s->next=NULL;}}return OK;}//ListInsert2void DeleteElem(LinkList &L,int aStartAddr)//*****删除线性表中始址值为aStartAddr的结点{LinkList p=L,q;while(p->next!=NULL){q=p->next;if(q->aStartAddr==aStartAddr){p->next=q->next;free(q);}elsep=p->next;}}//DeleteElem////////////////////////////////////////////////void PrintList(LinkList L)//AAA/*****输出各结点的值{printf("\n空闲分区情况: 始址\t 大小\n");LinkList p=L->next;while(p!=NULL){printf(" %d K\t%d KB\n",p->aStartAddr,p->areaSize);p=p->next;}printf("\n");}//PrintListvoid creatP(struct PCB *p){ //AAA/初始化进程int size;srand(time(NULL));size=rand()%7+1;size*=10;p->pNo=ppNo++;p->pSize=size;p->pOccupy=0;p->pStartAddr=0;p->pState=0;}int search(LinkList &L,int pSize){ //检索分区表 ,返回合适分区的首址LinkList p=L->next;while(p!=NULL){if(p->areaSize>=pSize){return p->aStartAddr;}p=p->next;}return -1;//没有足够大的int add(LinkList &L){ //返回空闲分区总和LinkList p=L->next;int sum=0;while(p!=NULL){sum+=p->areaSize;p=p->next;}return sum;}void pListPrint(struct PCB *pList){//AAA/输出存中空间占用情况printf("\n进程分配情况: 进程\t 始址\t占用\n");for(int i=0;i<pLength;i++){printf(" P%d\t %d K\t%d KB\n",pList[i].pNo,pList[i].pStartAddr,pList[i].pOccupy); }}void distribute(LinkList &L,struct PCB *process){LinkList p=L->next;while(p!=NULL){if(p->areaSize>=process->pSize)break;p=p->next;}printf("%d KB < %d KB",process->pSize,p->areaSize);if(p->areaSize-process->pSize<=SIZE){//不用分割全部分配(直接删除此空闲分区结点)process->pStartAddr=p->aStartAddr; //进程始址变化process->pState=1; //进程状态process->pOccupy=p->areaSize; //进程实际占用存为改空闲分区的大小pList[pLength++]= *process; //把进程加入进程列表printf(" 且 %d KB - %d KB = %d KB < %d KB 则整区分配\n", p->areaSize,process->pSize,p->areaSize-process->pSize,SIZE);pSort(pList);printf("\n分配后>>>>\n");pListPrint(pList);//输出存中空间占用情况DeleteElem(L,p->aStartAddr);}else{//分割分配process->pStartAddr=p->aStartAddr; //进程始址变化process->pState=1; //进程状态process->pOccupy=process->pSize; //进程实际占用存为该进程的大小pList[pLength++]= *process; //把进程加入进程列表printf(" 且 %d KB - %d KB = %d KB > %d KB 则划分分配\n",p->areaSize,process->pSize,p->areaSize-process->pSize,SIZE);pSort(pList); //进程排序printf("\n分配后>>>>\n");pListPrint(pList);//输出存中空间占用情况//compact(L,pList);p->aStartAddr+=process->pSize; //空闲分区始址变化p->areaSize-=process->pOccupy; //空闲分区大小变化}}int main(){//0、创建一个进程,参数随机数方式产生struct PCB p;int i,num,dele,k,stAddr,flag;LinkList s,L;printf("********************************可重定位分区分配********************************");if(!InitList(L)) //初始化空闲分区表printf("创建表失败\n");while(1){srand(time(0));flag=rand()%100+1;if(flag%2==0){creatP(&p);//初始化进程printf("___________________________________________________________________ _____________");printf("待装入作业:%d Size = %d KB\n",p.pNo,p.pSize);//1、请求分配 size//2、检索空闲分区表(首次适应FF)PrintList(L);stAddr=search(L,p.pSize);//得到足够大的分区的始址,没有则返回-1if(stAddr==-1){//没有足够大的分区if(add(L)>=p.pSize){//空闲区总和足够大printf("没有足够大的空闲分区但空闲总和足够大\n");//紧凑compact(L,pList);//按动态分区方式分配distribute(L,&p);//compact(L,pList); //紧凑}else{ //空闲区总和不足printf("分配失败\n\n");}}else{//有足够大的distribute(L,&p);PrintList(L);//compact(L,pList); //紧凑}}else{//回收if(pLength>0){recycle(L,pList);//compact(L,pList); //紧凑}else{printf("无可回收存! ");}}system("pause");} //whilereturn 0;}4.结果及其相关分析图4.1分析:作业1大小为20KB。