动态分区存储管理的模拟实现.docx
《动态分区存储管理的模拟实现.docx》由会员分享,可在线阅读,更多相关《动态分区存储管理的模拟实现.docx(14页珍藏版)》请在冰豆网上搜索。
动态分区存储管理的模拟实现
计算机科学与工程学院学生实验报告
专业
计算机科学与技术
班级
学号
姓名
课程名称
操作系统
课程类型
专业必修课
实验名称
动态分区存储管理的模拟实现
实验目的:
1.熟悉动态分区存储管理方式下,主存空间的分配和回收算法。
2.提高C语言编程能力。
实验内容:
假设主存当前状态如右表所示:
系统采用最佳适应分配算法为作业分配主存空间,而且具有紧凑技术。
请编程完成以下操作:
(1).输出此时的已分配区表和未分配区表;
(2).装入Job3(15K),输出主存分配后的已分配区表和未分配区表;
(3).回收Job2所占用的主存空间,输出主存回收后的已分配区表和未分配区表;
(4).装入Job4(130K),输出主存分配后的已分配区表和未分配区表。
实验要求
1.数据结构参考定义如下,也可根据需要进行改进:
(1)已分配区表:
#definen10/*假定系统允许的最大作业数量为n,n值为10*/
struct
{intnumber;/*序号*/
intaddress;/*已分配分区起始地址,单位为KB*/
intlength;/*已分配分区长度,单位KB*/
floatflag;/*已分配区表登记栏标志,0:
空表项,否则为作业名;*/
}used_table[n];/*已分配区表*/
(2)未分配区表:
#definem10/*假定系统允许的空闲区表最大为m,m值为10*/
struct
{intnumber;/*序号*/
intaddress;/*空闲区起始地址,单位为KB*/
intlength;/*空闲区长度,单位为KB*/
intflag;/*空闲区表登记栏标志,0:
空表项;1:
空闲区*/
}free_table[m];/*空闲区表*/
2.以allocate命名主存分配所用的过程或函数(算法参考课件),要将各种情况考虑周全。
3.以reclaim命名主存回收所用的过程或函数(算法参考课件),要将各种情况考虑周全。
4.画出算法实现的N-S流程图。
5.程序调试、运行成功后,请老师检查。
实验步骤:
1.分配内存,结果如下图:
2.回收内存,结果如下图:
3.合并内存,结果如下图:
4.N-S流程图:
4.1内存分配流程图:
4.2内存回收流程图:
附录程序代码:
#define_CRT_SECURE_NO_WARNINGS1
#include
#include
enumSTATE
{
Free,
Busy
};
structsubAreaNode
{
intaddr;//起始地址
intsize;//分区大小
inttaskId;//作业号
STATEstate;//分区状态
subAreaNode*pre;//分区前向指针
subAreaNode*nxt;//分区后向指针
}subHead;
//初始化空闲分区链
voidintSubArea()
{
//分配初始分区内存
subAreaNode*fir=(subAreaNode*)malloc(sizeof(subAreaNode));
//给首个分区赋值
fir->addr=0;
fir->size=240;//内存初始大小
fir->state=Free;
fir->taskId=-1;
fir->pre=&subHead;
fir->nxt=NULL;
//初始化分区头部信息
subHead.pre=NULL;
subHead.nxt=fir;
}
//最佳适应算法
intbestFit(inttaskId,intsize)
{
subAreaNode*tar=NULL;
inttarSize=240+1;
subAreaNode*p=subHead.nxt;
while(p!
=NULL)
{
//寻找最佳空闲区间
if(p->state==Free&&p->size>=size&&p->size{
tar=p;
tarSize=p->size;
}
p=p->nxt;
}
if(tar!
=NULL)
{
//分配大小为size的区间
subAreaNode*node=(subAreaNode*)malloc(sizeof(subAreaNode));
node->addr=tar->addr+size;
node->size=tar->size-size;
node->state=Free;
node->taskId=-1;
//修改分区链节点指针
node->pre=tar;
node->nxt=tar->nxt;
if(tar->nxt!
=NULL)
{
tar->nxt->pre=node;
}
tar->nxt=node;
//分配空闲区间
tar->size=size;
tar->state=Busy;
tar->taskId=taskId;
printf("内存分配成功!
\n");
return1;
}
else
{
printf("找不到合适的内存分区,分配失败...\n");
return0;
}
}
//回收内存
intfreeSubArea(inttaskId)
{
intflag=0;
subAreaNode*p=subHead.nxt,*pp;
while(p!
=NULL)
{
if(p->state==Busy&&p->taskId==taskId)
{
flag=1;
if((p->pre!
=&subHead&&p->pre->state==Free)
&&(p->nxt!
=NULL&&p->nxt->state==Free))
{
//情况1:
合并上下两个分区
//先合并上区间
pp=p;
p=p->pre;
p->size+=pp->size;
p->nxt=pp->nxt;
pp->nxt->pre=p;
free(pp);
//后合并下区间
pp=p->nxt;
p->size+=pp->size;
p->nxt=pp->nxt;
if(pp->nxt!
=NULL)
{
pp->nxt->pre=p;
}
free(pp);
}
elseif((p->pre==&subHead||p->pre->state==Busy)
&&(p->nxt!
=NULL&&p->nxt->state==Free))
{
//情况2:
只合并下面的分区
pp=p->nxt;
p->size+=pp->size;
p->state=Free;
p->taskId=-1;
p->nxt=pp->nxt;
if(pp->nxt!
=NULL)
{
pp->nxt->pre=p;
}
free(pp);
}
elseif((p->pre!
=&subHead&&p->pre->state==Free)
&&(p->nxt==NULL||p->nxt->state==Busy))
{
//情况3:
只合并上面的分区
pp=p;
p=p->pre;
p->size+=pp->size;
p->nxt=pp->nxt;
if(pp->nxt!
=NULL)
{
pp->nxt->pre=p;
}
free(pp);
}
else
{
//情况4:
上下分区均不用合并
p->state=Free;
p->taskId=-1;
}
}
p=p->nxt;
}
if(flag==1)
{
//回收成功
printf("内存分区回收成功...\n");
return1;
}
else
{
//找不到目标作业,回收失败
printf("找不到目标作业,内存分区回收失败...\n");
return0;
}
}
//显示空闲分区链情况
voidshowSubArea()
{
printf("*********************************************\n");
printf("当前的内存分配情况如下:
\n");
printf("*********************************************\n");
printf("起始地址|空间大小|工作状态|作业号\n");
subAreaNode*p=subHead.nxt;
while(p!
=NULL)
{
printf("**-----------------------------------------**\n");
printf("**");
printf("%3dk|",p->addr);
printf("%3dk|",p->size);
printf("%s|",p->state==Free?
"Free":
"Busy");
if(p->taskId>0)
{
printf("%2d",p->taskId);
}
else
{
printf("");
}
printf("**\n");
p=p->nxt;
}
printf("*********************************************\n");
}
intmain()
{
intoption,ope,taskId,size;
//初始化空闲分区链
intSubArea();
//模拟动态分区分配算法
while
(1)
{
printf("\n");
//printf("*********************************************\n");
printf("1:
分配内存2:
回收内存0:
退出\n");
printf("*********************************************\n");
scanf("%d",&ope);
if(ope==0)break;
if(ope==1){
//模拟分配内存
printf("请输入作业号:
");
scanf("%d",&taskId);
printf("请输入需要分配的内存大小(KB):
");
scanf("%d",&size);
if(size<=0)
{
printf("错误:
分配内存大小必须为正值\n");
continue;
}
//调用分配算法
bestFit(taskId,size);
//显示空闲分区链情况
showSubArea();
}
elseif(ope==2)
{
//模拟回收内存
printf("请输入要回收的作业号:
");
scanf("%d",&taskId);
freeSubArea(taskId);
//显示空闲分区链情况
showSubArea();
}
else
{
printf("错误:
请输入0/1/2\n");
}
}
printf("分配算法模拟结束\n");
system("pause");
return0;
}
实验总结:
通过本次实验,基本实现了内存分配和内存回收,内存分配中所运用的算法是最佳适应分配算法,但是该程序没有实现紧凑性,程序其他方面没有问题。
实验评语:
实验成绩
教师签名