存储管理动态分区分配算法的模拟Word格式.docx
《存储管理动态分区分配算法的模拟Word格式.docx》由会员分享,可在线阅读,更多相关《存储管理动态分区分配算法的模拟Word格式.docx(32页珍藏版)》请在冰豆网上搜索。
intid;
/*作业ID*/
/*作业大小(需要的存储空间大小)*/
intstatus;
/*作业状态0:
newjob,1:
inthememory,2:
finished.*/
structjobList*next;
/*作业链表指针*/
以上将存储空间分为空闲可占用两部分,在usedlist中设jobID而不设size,可以在不增加空间复杂度(与freelist相比)的同时更方便的实现可变分区存储管理(从后面的一些函数的实现上可以得出这个结论)。
尽管设置joblist增加了空间复杂度,但它的存在,使得该程序可以方便的直接利用D盘中的JOB文件。
该文件可以认为是一个和其他进程共享的资源。
通过这个文件,其他进程写入数据供读取。
这中思想在操作系统设计中体现的很多。
2.实现分区存储管理的内存分配功能,选择适应算法(首次适应算法,最佳适应算法,最后适应算法,最坏适应算法)。
基本原理分析:
1)Bestfit:
将空闲分区按大小从小到大排序,从头找到大小合适的分区。
2)Worstfit:
将空闲分区按大小从大到小排序,从头找到大小合适的分区。
3)Firstfit:
将空闲分区按起始地址大小从小到大排序,……
4)Lastfit:
将空闲分区按起始地址大小从大到小排序,……
由此,可将空闲分区先做合适的排序后用对应的适应算法给作业分配存储空间。
排序函数order(bySize为零则按分区大小排序,否则按分区起始地址;
inc为零从小到大排序,否则从大到小排序;
通过empty指针返回结果)。
voidorder(structfreeList**empty,intbySize,intinc)
structfreeList*p,*q,*temp;
intstartAddress,size;
for(p=(*empty)->
next;
p;
p=p->
next)
{/*按bySize和inc两个参数寻找合适的节点,用temp指向它*/
for(temp=q=p;
q;
q=q->
{
switch(bySize)
{
case0:
switch(inc)
{
case0:
if(q->
size<
temp->
size)
temp=q;
break;
default:
size>
}break;
default:
startAddress<
startAddress)
startAddress>
}
}/*交换节点的成员值*/
if(temp!
=p)
{
startAddress=p->
startAddress;
size=p->
size;
p->
startAddress=temp->
size=temp->
temp->
startAddress=startAddress;
size=size;
}
}
3.实现分区存储管理的内存回收算法。
voidinsertFreeNode(structfreeList**empty,intstartAddress,intsize)
插入回收的空节点分区,处理回收分区与空闲分区的四种邻接关系。
structfreeList*p,*q,*r;
for(p=*empty;
p->
next);
/*处理链表尾部的邻接情况*/
if(p==*empty||p->
startAddress+p->
size<
startAddress)
/*与尾部不相邻*/
{
makeFreeNode(&
r,startAddress,size);
/*通过r指针返回创建的空闲节点*/
r->
next=p->
/*插入独立的空闲节点*/
p->
next=r;
return;
if(p->
size==startAddress)/*与尾部上邻*/
size+=size;
/*合并尾部节点*/
q=(*empty)->
/*处理链表首节点的邻接情况*/
if(startAddress+size==q->
startAddress)/*与首节点下邻*/
q->
startAddress=startAddress;
/*合并首节点*/
elseif(startAddress+size<
q->
/*与首节点不相邻*/
next=(*empty)->
(*empty)->
else
{/*处理链表中间的邻接情况*/
while(q->
next&
&
startAddress<
p=q;
q=q->
if(p->
size==startAddress&
\
startAddress==startAddress+size)
/*上下邻,合并节点*/
p->
size+=size+q->
size;
next=q->
free(q);
/*删除多余节点*/
elseif(p->
q->
startAddress!
=startAddress+size)
/*上邻,增加节点的大小*/
p->
size!
=startAddress&
q->
startAddress==startAddress+size)/*下邻*/
/*修改节点起始地址*/
/*修改节点的大小*/
else
{/*上下不相邻*/
makeFreeNode(&
r->
4.当碎片产生时,进行碎片的拼接。
voidmoveFragment(structjobList*jobs,structfreeList**empty,structusedList**used)
intsize,status;
structusedList*p;
intaddress=memoryStartAddress;
/*全局变量,初始化时分配存储空间始址*/
if((*empty)->
next==NULL)/*空闲分区链表为空,提示并返回*/
printf("
\nThememorywasusedoutatall.\nMaybeyoushouldfinishsomejobsfirstorpressanykeytotryagain!
"
);
getch();
return;
for(p=(*used)->
p=p->
/*循环的修改占用分区的始址*/
startAddress=address;
getJobInfo(jobs,p->
jobID,&
size,&
status);
/*由作业ID获得作业大小*/
address+=size;
(*empty)->
next->
startAddress=address;
/*修改空闲分区的首节点始址、大小*/
(*empty)->
next->
size=memorySize-(address-memoryStartAddress);
next=NULL;
/*删除首节点后的所有节点*/
5.空闲分区队列显示:
intshowFreeList(structfreeList*empty)
6.作业占用链表显示:
intshowUsedList(structjobList*jobs,structusedList*used)
从头到尾显示used链,同时通过其中的作业ID在jobs中查对应的大小。
7.从键盘输入作业到D盘的JOB文件:
voidinputJob(void)
8.从JOB文件中读出作业并创建作业链表:
intmakeJobList(structjobList**jobs)
9.显示作业链表:
intshowJobList(structjobList*jobs)
10.更新作业链表中作业的状态:
intupdateJobFile(structjobList*jobs)
11.根据作业链表更新JOB文件:
intupdateJobFile(structjobList*jobs)
12.为作业分配存储空间、状态必须为0:
intallocate(structfreeList**empty,intsize)
13.结束一个作业号为id的作业,释放存储空间(由*startAddress返回空间的起始地址):
intfinishJob(structusedList**used,intid,int*startAddress)
14.插入释放的空间到used链表中(作业号为id,startAddress由函数13返回):
voidinsertUsedNode(structusedList**used,intid,intstartAddress)
15.获取作业的信息:
voidgetJobInfo(structjobList*jobs,intid,int*size,int*status)
16.初始化存储空间起始地址、大小:
voidiniMemory(void)
17.选择适应算法:
charselectFitMethod(void)
18.根据参数startAddress、size创建空闲节点,由empty指针返回:
voidmakeFreeNode(structfreeList**empty,intstartAddress,intsize)
19.以要求的方式打开文件:
voidopenFile(FILE**fp,char*filename,char*mode)
20.出现严重错误时显示信息并结束程序;
voiderrorMessage(void)
六、算法流程
1、DynamicZonalMemoryManagement
其中1、Initializiation.按顺序利用了openFile()、iniMemory()、makeFreeNode()、inputJob()(选择利用D盘JOB文件时提供作业信息)、makeJobList()、allocate()、insertUsedNode()(选择利用D盘JOB文件时先将状态为1的作业放到存储空间中,以恢复上次的模拟实验,或使本次模拟时不出错)selectFitMethod()等自编函数。
2、Putjobintomemory(allocatememory)按顺序利用了showJobList()(选手动逐个为作业分配存储空间时)、openFile()、order()、allocate()、errorMessage()、insertUsedNode()、updateJobStatus()updateJobFile()函数
3、Finishjob(reusememory)按顺序利用了openFile()、showUsedList()、getJobInfo()、insertFreeNode()、updateJobStatus()、updateJobFile()、errorMessage()等自编函数。
4、Showcurrentfreelist按顺序利用了openFile()、showFreeList()函数。
5、Showcurrentmemoryusedbyjobs按顺序利用了openFile()、showUsedList()函数。
6、Movefragmenttogether按顺序利用了openFile()、moveFragment()函数。
7、Exit按顺序利用了openFile()、exit(0)函数。
七、程序清单
1、原程序
#include<
stdio.h>
time.h>
stdlib.h>
intmemoryStartAddress=-1;
intmemorySize=-1;
/*作业ID*/
/*作业大小(需要的存储空间大小)*/
};
structfreeList
intstartAddress;
/*分区起始地址*/
intsize;
/*分区大小*/
structfreeList*next;
/*分区链表指针*/
/*分区中存放作业ID*/
voiderrorMessage(void)/*出现严重错误时显示信息并结束程序*/
printf("
\n\tError!
\a"
\nPressanykeytoexit!
getch();
exit
(1);
voidopenFile(FILE**fp,char*filename,char*mode)
/*以要求的方式打开文件*/
if((*fp=fopen(filename,mode))==NULL)
printf("
\nCan'
topen%sinmode%s."
filename,mode);
errorMessage();
voidmakeFreeNode(structfreeList**empty,intstartAddress,intsize)
/*根据参数startAddress、size创建空闲节点,由empty指针返回*/
if((*empty=malloc(sizeof(structfreeList)))==NULL)
\nNotenoughtoallocateforthefreenode."
next=NULL;
voidiniMemory(void)/*初始化存储空间起始地址、大小*/
charMSA[10],MS[10];
\nPleaseinputthestartaddressofthememory!
scanf("
%s"
MSA);
memoryStartAddress=atoi(MSA);
\nPleaseinputthesizeofthememory!
MS);
memorySize=atoi(MS);
charselectFitMethod(void)/*选择适应算法*/
FILE*fp;
charfitMethod;
do{
\n\nPleaseinputacharasfallowtoselectthefitmethod!
\n1(Bestfit)\
\n2(Worstfit)\
\n3(Firstfit)\
\n4(Lastfit)\n"
fitMethod=getche();
}while(fitMethod<
'
1'
||fitMethod>
4'
openFile(&
fp,"
d:
\\result.cl"
"
a"
switch(fitMethod)
case'
:
fprintf(fp,"
\n\n\n\n\tBestfit"
\n**********************************************"
break;
2'
\n\n\n\n\tWorstfit"
fprintf(fp,"
3'
\n\n\n\n\tFirstfit"
\n\n\n\n\tLastfit"
fprintf(fp,"
fclose(fp);
returnfitMethod;
voidinputJob(void)/*从键盘输入作业到D盘的JOB文件*/
int/*id,size,*/status=0,jobnum=0;
charid[10],size[10];
openFile(&
\\job.cl"
w"
job_ID\tsize\tstatus"
\n\n\n\nPleaseinputthejobsasfallow!
\nEnteraintegersmallerthan1toquit.\njob_ID\tsize\n"
/*scanf("
%d%d"
&
id,&
size);
*/
scanf("
%s\t%s"
id,size);
if(atoi(id)>
0&
atoi(size)>
0)
\n%s\t%s\t%d"
id,size,status);