操作系统的主存储器空间地分配和回收Word文档下载推荐.docx
《操作系统的主存储器空间地分配和回收Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《操作系统的主存储器空间地分配和回收Word文档下载推荐.docx(24页珍藏版)》请在冰豆网上搜索。
有时找到的空闲区可能大于作业需要量,这时应把原来的空闲区变成两部分:
一部分分给作业占用;
另一部分又成为一个较小的空闲区。
为了尽量减少由于分割造成的空闲区,而尽量保存高地址部分有较大的连续空闲区域,以利于大型作业的装入。
为此,在空闲区说明表中,把每个空闲区按其地址顺序登记,即每个后继的空闲区其起始地址总是比前者大。
为了方便查找还可使表格“紧缩”,总是让“空表目”栏集中在表格的后部。
(3)采用最先适应算法(顺序分配算法)分配主存空间。
按照作业的需要量,查空闲区说明表,顺序查看登记栏,找到第一个能满足要求的空闲区。
当空闲区大于需要量时,一部分用来装入作业,另一部分仍为空闲区登记在空闲区说明表中。
由于本实习是模拟主存的分配,所以把主存区分配给作业后并不实际启动装入程序装入作业,而用输出“分配情况”来代替。
最先适应分配算法如图4-1。
(4)当一个作业执行结束撤离时,作业所占的区域应该归还,归还的区域如果与其它空闲区相邻,则应合成一个较大的空闲区,登记在空闲区说明表中。
例如,在提示
(1)中列举的情况下,如果作业2撤离,归还所占主存区域时,应与上、下相邻的空闲区一起合成一个大的空闲区登记在空闲区说明表中。
归还主存时的回收算法如图4-2。
(5)请按最先适应算法设计主存分配和回收的程序。
然后按
(1)中假设主存中已装入三个作业,且形成两个空闲区,确定空闲区说明表的初值。
现有一个需要主存量为6K的作业4申请装入主存;
然后作业3撤离;
再作业2撤离。
请你为它们进行主存分配和回收,把空闲区说明表的初值以及每次分配或回收后的变化显示出来或打印出来。
二,本实验用到的一些数据结构有:
typedefstructNODE
{
charname;
//名称
floatstart;
//起始位置
floatend;
//大小
intflag;
//是否分配的标志
}NODE;
NODEOS[COUNT];
//数组
三,流程图
四,源代码
#include<
stdio.h>
#include<
math.h>
#defineCOUNT512
intcount;
//被分成的块数统计
intapplyfree;
floatnumb;
charc;
//先对数组进行初始化,使没有分配的名称为P
voidinit()
count=1;
OS[0].name='
P'
;
OS[0].start=0;
OS[0].end=COUNT;
OS[0].flag=1;
}
//对数组的插入操作
voidinsert(intm,floatst,floaten)
inti;
count++;
for(i=count;
i>
m+1;
i--)
{
OS[i]=OS[i-1];
}
OS[m].start=st;
OS[m].end=en;
//移动操作,即对数组的删除操作
voidmove(intm)
for(i=m;
i<
count-1;
i++)
OS[i]=OS[i+1];
count--;
//如果相邻块都没有分配,则要合并到一起
voidrremove(intm,floatst,floaten)
if(!
OS[m-1].flag&
&
!
OS[m+1].flag)
OS[m].name='
OS[m].flag=1;
if(OS[m-1].flag)
OS[m-1].end=OS[m-1].end+en;
move(m);
if(OS[m+1].flag)
OS[m].end=OS[m].end+OS[m+1].end;
move(m+1);
//打印输出
voidshow()
printf("
名称标识起址长度状态\n"
);
for(i=0;
count;
if(OS[i].flag)
printf("
P"
else
%c"
OS[i].name);
printf("
%d%1.0f%1.0f"
i,OS[i].start,OS[i].end);
未分配\n"
已分配\n"
//从键盘输入数据
voidputin()
请输入申请或者释放的进程名称及资源数量:
\n"
rewind(stdin);
scanf("
%c"
&
c);
%d"
applyfree);
%f"
numb);
intapply()
inti=0;
intapplyflag=0;
intfreeflag=0;
if(applyfree)//提出申请资源
while(!
applyflag&
count)
{
if(OS[i].end>
=numb&
OS[i].flag)
{
if(OS[i].end==numb)
{
OS[i].name=c;
OS[i].flag=0;
}
else
insert(i+1,OS[i].start+numb,OS[i].end-numb);
OS[i+1].flag=1;
OS[i+1].name='
OS[i].start=OS[i].start;
OS[i].end=numb;
applyflag=1;
}
i++;
}
if(applyflag)
申请成功!
return1;
申请失败!
没有足够大的空闲空间。
return0;
else//提出释放资源
freeflag&
if(OS[i].name==c)
rremove(i,OS[i].start,OS[i].end);
if(OS[i].end>
numb)
{
insert(i+1,OS[i].start+numb,OS[i].end-numb);
OS[i+1].name='
OS[i+1].flag=0;
OS[i].end=numb;
OS[i].flag=1;
if(OS[i-1].flag)
{
rremove(i,OS[i].start,OS[i].end);
}
}
else
printf("
释放失败,因为正使用的数量小于要求释放的数量。
return0;
freeflag=1;
if(freeflag)
释放成功!
释放失败!
未找到匹配的进程名称。
voidmain()
init();
show();
while
(1)
putin();
apply();
show();
五,执行结果
空闲区说明表的初始状态
作业4的申请量以及为作业4分配后的空闲区说明表状态
作业3和作业2的归还量以及回收作业3,作业2所占主存后的空闲区说明表
第二题:
在分页式管理方式下采用位示图来表示主存分配情况,实现主存空间的分配和回收。
(1)分页式存储器把主存分成大小相等的若干块,作业的信息也按块的大小分页,作业装入主存时可把作业的信息按页分散存放在主存的空闲块中,为了说明主存中哪些块已经被占用,哪些块是尚未分配的空闲块,可用一张位示图来指出。
位示图可由若干存储单元来构成,其中每一位与一个物理块对应,用0/1表示对应块为空闲/已占用。
(2)假设某系统的主存被分成大小相等的64块,则位示图可用8个字节来构成,另用一单元记录当前空闲块数。
如果已有第0,1,4,5,6,9,11,13,24,31,共10个主存块被占用了,那么位示图情况如下:
字位
节数
号
1
2
3
4
5
6
7
0
1
2
3
4
5
6
7
图4-1最先适应分配模拟算法
图4-2主存回收算法
(3)当要装入一个作业时,根据作业对主存的需要量,先查当前空闲块数是否能满足作业要求,若不能满足则输出分配不成功。
若能满足,则查位示图,找出为“0”的一些位,置上占用标志“1”,从“当前空闲块数”中减去本次占用块数。
按找到的计算出对应的块号,其计算公式为:
块号=j8+i
其中,j表示找到的是第n个字节,I表示对应的是第n位。
根据分配给作业的块号,为作业建立一张页表,页表格式:
页号
块号
(4)当一个作业执行结束,归还主存时,根据该作业的页表可以知道应归还的块号,由块号可计算出在位示图中的对应位置,把对应位的占用标志清成“0”,表示对应的块已成为空闲块。
归还的块数加入到当前空闲块数中。
由块号计算在位示图中的位置的公式如下:
字节号j=[块号/8]([]表示取整)
位数i={块号/8}({}表示取余)
(5)设计实现主存分配和回收的程序。
假定位示图的初始状态如
(2)所述,现有一信息量为5页的作业要装入,运行你所设计的分配程序,为作业分配主存且建立页表(格式如(3)所述)。
然后假定有另一作业执行结束,它占用的块号为第4,5,6和31块,运行你所设计的回收程序,收回作业归还的主存块。
要求能显示和打印分配或回收前后的位示图和当前空闲块数,对完成一次分配后还要显示或打印为作业建立的页表。
二,源代码
#defineN64//物理块数
#defineM100000//最多输入文件数
structfile//文件结构体,包含文件号,文件页长,页号,几页号对应的块号
intfilenum;
intyechang;
intyenum;
intkuainum;
};
structfilefl[N];
//文件结构体数组
voidput(inta[8][8])//输出位示图
inti,j;
8;
for(j=0;
j<
j++)
\t%d"
a[i][j]);
voidhuishou(inta[8][8],intb)//回收规定的页面
intc[4]={4,5,6,31};
inti,j,k,empty;
inth[4];
for(k=0;
k<
4;
k++)
h[k]=c[k];
i=c[k]/8;
j=c[k]%8;
a[i][j]=0;
\n需要回收的页号和块号分别为:
页号\t块号\n"
%d\t%d\n"
k,h[k]);
回收后的页表位示图为:
put(a);
empty=0;
if(a[i][j]==1)
empty+=1;
empty=64-empty;
剩余的块数:
%d\n"
empty);
voidshixian(inta[8][8],intb)//实现存储空间的分配与回收
inti,j,k,x,y,m,empty,full,fileshu,kuainum,h[N],g[N][N];
intcishu=0,hang=0,lie=0,filenum=0,wenjianshu=0;
intp[M]={-1};
intjian=0;
empty=b;
beg:
请输入需要装入的文件的页数:
"
m);
cishu=0;
if(empty<
m)
需要装入的页数大于页表中的空闲页数,分配失败\n"
else
wenjianshu+=1;
for(i=1;
=wenjianshu;
if(fl[i].yechang==0)
filenum=i;
filenum+=1;
h[filenum]=m;
fl[filenum].filenum=filenum;
m;
fl[filenum].yenum=i;
for(i=0;
if(a[i][j]==0)
a[i][j]=1;
kuainum=i*8+j;
cishu+=1;
fl[filenum].yenum=cishu;
fl[filenum].kuainum=kuainum;
g[filenum][cishu]=kuainum;
if(cishu>
=m)
break;
if(cishu>
break;
fl[filenum].yechang=m;
文件号:
%d\t文件页长:
fl[filenum].filenum,
fl[filenum].yechang);
%d\t"
fl[filenum].yenum-m+i);
g[filenum][i+1]);
full=0;
full+=1;
}
empty=64-full;
分配后的页表位示图为:
put(a);
继续装入文件请输入1,回收页面请输入2,输入其他键结束:
scanf("
y);
if(y==1)
gotobeg;
elseif(y==2)
gotoaeg;
gotoend;
aeg:
请输入需要回收的文件号大于0且不在下列数集中的数---\t"
for(i=1;
=jian;
if(p[jian]!
=-1)
p[jian]);
\n输入的需要回收的页数为:
fileshu);
if(wenjianshu<
fileshu)
你输入的文件号不存在!
if(fileshu<
=0)
k=g[fileshu][1];
filenum=fileshu;
for(x=0;
x<
h[fileshu];
x++)
k=g[fileshu][x+1];
i=k/8;
j=k%8;
a[i][j]=0;
回收页面后的页表位示图为:
empty=0;
//显示空闲页数
empty=64-empty;
fl[fileshu].yechang=0;
jian+=1;
p[jian]=fileshu;
继续装入页面请输入1,回收页面请输入2,输入其他键结束:
if(y==1)
elseif(y==2)
gotoaeg;
end:
huishou(a,empty);
inti,j,b,m,n;
intc[N]={0,1,4,5,6,9,11,13,24,31};
inta[8][8]={0};
for(m=0;
m<
10;
m++)
i=c[m]/8;
j=c[m]%8;
a[i][j]=1;
初始化的位示图是:
b=0;
b=b+1;
n=64-b;
n);
shixian(a,n);
三,执行结果