《操作系统实验内存分配(共11页).doc》由会员分享,可在线阅读,更多相关《操作系统实验内存分配(共11页).doc(11页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、精选优质文档-倾情为你奉上实验四 存储器管理一、实验名称:存储器管理二、实验目的在TC、VB、Delphi、C+Builder等语言与开发环境中,模拟操作系统的内存管理;通过程序运行所显示的内存使用的各项指标,加深对内存管理的理解。三、实验内容实现主存储器空间的分配和回收。本实验有两个题,学生可选择其中的一题做实验。第一题:在固定分区管理方式下实现主存分配和回收。第二题:在可变分区管理方式下采用最先适应算法实现主存分配和实现主存回收。提示:可变分区方式是按作业需要的主存空间大小来分割分区的。当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作
2、业;若无,则作业不能装入。随着作业的装入、撤离,主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。为了说明哪些区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,格式如下:起 址长 度状 态第一栏14 K12 K未 分 配第二栏32 K96 K未 分 配MM空 表 目空 表 目MM其中,起址指出一个空闲区的主存起始地址。 长度指出从起始地址开始的一个连续空闲的长度。状态有两种状态,一种是“未分配”状态,指出对应的由起址指出的某个长度的区域是空闲区;另一种是“空表目”状态,表示表中对应的登记项目是空白(无效),可用来登记新的空闲区(例如,作业撤离后,它所占的区域就成了空闲区
3、,应找一个“空表目”栏登记归还区的起址和长度且修改状态)。由于分区的个数不定,所以空闲区说明表中应有适量的状态为“空表目”的登记栏目,否则造成表格“溢出”无法登记。空闲区表的定义为:#define m 10 /*假定系统允许的空闲区表最大为m*/struct float address; /*起始地址*/ float length; /*长度*/ int flag; /*标志,用“0”表示空栏目,用“1”表示未分配*/ free_tablem; /*空闲区表*/上述的这张说明表的登记情况是按提示(1)中的例所装入的三个作业占用的主存区域后填写的。(2) 当有一个新作业要求装入主存时,必须查空闲
4、区说明表,从中找出一个足够大的空闲区。有时找到的空闲区可能大于作业需要量,这时应把原来的空闲区变成两部分:一部分分给作业占用;另一部分又成为一个较小的空闲区。为了尽量减少由于分割造成的空闲区,而尽量保存高地址部分有较大的连续空闲区域,以利于大型作业的装入。为此,在空闲区说明表中,把每个空闲区按其地址顺序登记,即每个后继的空闲区其起始地址总是比前者大。为了方便查找还可使表格“紧缩”,总是让“空表目”栏集中在表格的后部。(3) 采用最先适应算法(顺序分配算法)分配主存空间。按照作业的需要量,查空闲区说明表,顺序查看登记栏,找到第一个能满足要求的空闲区。当空闲区大于需要量时,一部分用来装入作业,另一
5、部分仍为空闲区登记在空闲区说明表中。由于本实验是模拟主存的分配,所以把主存区分配给作业后并不实际启动装入程序装入作业,而用输出“分配情况”来代替。最先适应分配算法如图3-1。图3-1 最先适应分配模拟算法(4) 当一个作业执行结束撤离时,作业所占的区域应该归还,归还的区域如果与其它空闲区相邻,则应合成一个较大的空闲区,登记在空闲区说明表中。例如,在提示(1)中列举的情况下,如果作业2撤离,归还所占主存区域时,应与上、下相邻的空闲区一起合成一个大的空闲区登记在空闲区说明表中。归还主存时的回收算法如图3-2。图32 主存回收算法(5) 请按最先适应算法设计主存分配和回收的程序。然后按(1)中假设主
6、存中已装入三个作业,且形成两个空闲区,确定空闲区说明表的初值。现有一个需要主存量为6K的作业4申请装入主存;然后作业3撤离;再作业2撤离。请你为它们进行主存分配和回收,把空闲区说明表的初值以及每次分配或回收后的变化显示出来或打印出来。第一题#include stdio.h#include stdlib.h#include conio.h#define N 5struct tableint num;int size;char add4;bool state;int kN=0;void display(table aN);void hs(table aN);void fp(table aN);vo
7、id main()table aN;for(int i=0;iN;i+)printf(输入分区%d的大小,i+1);ai.num=i+1;scanf(%d,&ai.size);printf(输入分区%d的地址,i+1);scanf(%s,&ai.add);ai.state=true;printf( 初始状态为:n);display(a);char c;int flag=1;while(flag)printf(n是否分配分区?是:Y 回收分区:N 结束程序:En);c=getche();if(c=N|c=n)hs(a);else if(c=Y|c=y)fp(a);else if(c=e|c=E)
8、flag=0;else flag=0;void fp(table aN)int xk;printf(n输入需要分区的大小n);scanf(%d,&xk);for(int j=0;jN;j+)if(aj.state=false)continue;elseif(aj.sizexk)continue;elseaj.state=false;break;if(j=N)printf(n所需分区太大不能分配,请重新申请。nn);elsedisplay(a);void display(table aN)printf(分区号 | 大小 | 地址 | 状态 n);for(int i=0;iN;i+) printf
9、( %dt%dt%st%d n,ai.num,ai.size,ai.add,ai.state);void hs(table aN)printf(n请输入要回收的分区号:n);int i;scanf(%d,&i);if(ai-1.state!=false)printf(该分区未分配,不需回收n);else ai-1.state=true;display(a);第二题#include stdio.h#include stdlib.h#include math.h#define n 10 /*假定系统允许的最大作业为,假定模拟实验中n值为10*/#define m 10/*假定系统允许的空闲区表最大
10、为m,假定模拟实验中m值为10*/#define minisize 100struct float address; /*已分分区起始地址*/ float length; /*已分分区长度,单位为字节*/ int flag; /*已分配区表登记栏标志,用0表示空栏目*/used_tablen; /*已分配区表*/struct float address; /*空闲区起始地址*/ float length; /*空闲区长度,单位为字节*/ int flag; /*空闲区表登记栏标志,用0表示空栏目,用1表示未分配*/free_tablem; /*空闲区表*/allocate(char J,flo
11、at xk)/*采用最优分配算法分配xk大小的空间*/int i,k; float ad; k=-1; for(i=0;i=xk&free_tablei.flag=1) if(k=-1|free_tablei.lengthfree_tablek.length) k=i; if(k=-1)/*未找到可用空闲区,返回*/ printf(无可用空闲区n); return 1;/*找到可用空闲区,开始分配:若空闲区大小与要求分配的空间差小于msize大小,则空闲区全部分配;若空闲区大小与要求分配的空间差大于minisize大小,则从空闲区划出一部分分配*/ if(free_tablek.length-
12、xk=minisize) free_tablek.flag=0; ad=free_tablek.address; xk=free_tablek.length; else free_tablek.length=free_tablek.length-xk; ad=free_tablek.address+free_tablek.length; /*修改已分配区表*/ i=0; while(used_tablei.flag!=0&i=n) /*无表目填写已分分区*/ printf(无表目填写已分分区,错误n); /*修正空闲区表*/ if(free_tablek.flag=0) /*前面找到的是整个空
13、闲分区*/ free_tablek.flag=1; else /*前面找到的是某个空闲分区的一部分*/ free_tablek.length=free_tablek.length+xk; return 1; else/*修改已分配表*/ used_tablei.address=ad; used_tablei.length=xk; used_tablei.flag=J; return 1;/*主存分配函数结束*/reclaim(char J)/*回收作业名为J的作业所占主存空间*/ int i,k,j,s,t; float S,L; /*寻找已分配表中对应登记项*/ s=0; while(use
14、d_tables.flag!=J|used_tables.flag=0)&s=n)/*在已分配表中找不到名字为J的作业*/ printf(找不到该作业n); return 1; /*修改已分配表*/ used_tables.flag=0; /*取得归还分区的起始地址S和长度L*/ S=used_tables.address; L=used_tables.length; j=-1;k=-1;i=0; /*寻找回收分区的空闲上下邻,上邻表目k,下邻表目j*/ while(im&(j=-1|k=-1) if(free_tablei.flag=1) if(free_tablei.address+fre
15、e_tablei.length=S)k=i;/*找到上邻*/ if(free_tablei.address=S+L)j=i;/*找到下邻*/ i+; if(k!=-1) if(j!=-1) /* 上邻空闲区,下邻空闲区,三项合并*/ free_tablek.length=free_tablej.length+free_tablek.length+L; free_tablej.flag=0; else /*上邻空闲区,下邻非空闲区,与上邻合并*/ free_tablek.length=free_tablek.length+L; else if(j!=-1) /*上邻非空闲区,下邻为空闲区,与下邻
16、合并*/ free_tablej.address=S; free_tablej.length=free_tablej.length+L; else /*上下邻均为非空闲区,回收区域直接填入*/ /*在空闲区表中寻找空栏目*/ t=0; while(free_tablet.flag=1&t=m)/*空闲区表满,回收空间失败,将已分配表复原*/ printf(主存空闲表没有空间,回收空间失败n); used_tables.flag=J; return 0; free_tablet.address=S; free_tablet.length=L; free_tablet.flag=1; return
17、 0;/*主存回收函数结束*/void main( ) int i,a; float xk; char J; /*空闲分区表初始化:*/ free_table0.address=10240; free_table0.length=; free_table0.flag=1; for(i=1;im;i+) free_tablei.flag=0; /*已分配表初始化:*/ for(i=0;in;i+) used_tablei.flag=0; while(1) printf(选择功能项(0-退出,1-分配主存,2-回收主存,3-显示主存)n); printf(选择功项(03) :); scanf(%d
18、,&a); switch(a) case 0: printf(程序结束!n); exit(0); /*a=0程序结束*/ case 1: /*a=1分配主存空间*/ printf(输入作业名J和作业所需长度xk: ); scanf(%*c%c%f,&J,&xk); allocate(J,xk);/*分配主存空间*/ break; case 2: /*a=2回收主存空间*/ printf(输入要回收分区的作业名); scanf(%*c%c,&J); reclaim(J);/*回收主存空间*/ break; case 3: /*a=3显示主存情况*/ /*输出空闲区表和已分配表的内容*/ prin
19、tf(输出空闲区表:n起始地址 分区长度 标志n); for(i=0;im;i+) printf(%6.0f%9.0f%6dn,free_tablei.address,free_tablei.length, free_tablei.flag); /printf( 按任意键,输出已分配区表n); /getchar(); printf(输出已分配区表:n起始地址 分区长度 标志n); for(i=0;in;i+) if(used_tablei.flag!=0) printf(%6.0f%9.0f%6cn,used_tablei.address,used_tablei.length, used_tablei.flag); else printf(%6.0f%9.0f%6n,used_tablei.address,used_tablei.length, used_tablei.flag); break; default:printf(没有该选项n); /*case*/ /*while*/*主函数结束*/专心-专注-专业
限制150内