可变分区存储管理实验报告.docx
《可变分区存储管理实验报告.docx》由会员分享,可在线阅读,更多相关《可变分区存储管理实验报告.docx(16页珍藏版)》请在冰豆网上搜索。
可变分区存储管理实验报告
沈阳工程学院
学生实验报告
实验室名称:
信息工程系信息安全实验室
实验课程名称:
操作系统
实验项目名称:
可变分区存储管理
班级:
计专本121姓名:
郑永凯学号:
2012461127
实验日期:
2013年5月27日实验台编号:
F608
指导教师:
张楠
批阅教师(签字):
成绩:
【实验目的】
通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解。
【实验内容】
设计一个可变式分区分配的存储管理方案。
并模拟实现分区的分配和回收过程。
对分区的管理法可以采用下面三种算法之一:
1、首次适应算法;
2、循环首次适应算法;
3、最佳适应算法;
必须建立空闲区表和占用区表,回收算法考虑四种情况。
【实验要求】
1)上机前认真复习可变式分区分配算法,熟悉存储器分配和回收过程;
2)上机时独立编程、调试程序;
3)根据具体实验要求,完成好实验报告(包括实验的目的、内容、要求、源程序、实例运行结果截图)。
#include
#defineNULL0
#definegetjcb(type)(type*)malloc(sizeof(type))
#definegetsub(type)(type*)malloc(sizeof(type))
intnum,num2;//要调度的作业数和要回收的区域数
intm=0;//已分配作业数
intflag;//分配成功标志
intisup,isdown;//回收区域存在上邻和下邻的标志
intis=0;
structjcb{
charname[10];
charstate;
intntime;//所需时间
intsize;//所需空间大小
intaddr;//所分配分区的首地址
structjcb*link;
}*ready=NULL,*p,*q,*as=NULL;//作业队列ready,已分配作业队列as
typedefstructjcbJCB;
structsubarea{//分区块
intaddr;//分区首地址
intsize;//分区大小
structsubarea*link;
}*sub=NULL,*r,*s,*cur;//空闲分区队列sub,当前分区指针cur
typedefstructsubareaSUB;
voidsort()/*建立对作业按到达时间进行排列的函数,直接插在队列之尾*/
{
JCB*first;
if(ready==NULL)ready=p;
else{
first=ready;
while(first->link!
=NULL)
first=first->link;
first->link=p;
p->link=NULL;
}
voidsort3()/*建立对已分配作业队列的排列函数,直接插在队列之尾*/
JCB*fir;
if(as==NULL)as=q;
fir=as;
while(fir->link!
fir=fir->link;
fir->link=q;
q->link=NULL;
m++;
voidinput()/*建立作业控制块函数*/
inti;
printf("\n请输入要调度的总作业数:
");
scanf("%d",&num);
for(i=0;i{printf("\n作业号No.%d:\n",i);p=getjcb(JCB);printf("\n输入作业名:");scanf("%s",&p->name);printf("\n输入作业的大小:");scanf("%d",&p->size);printf("\n输入作业所需运行时间:");scanf("%d",&p->ntime);p->state='w';p->link=NULL;sort();/*调用sort函数*/}printf("\n按任一键继续......\n");getch();}voidinput2()/*建立要回收区域的函数*/{JCB*k;inthas;q=getjcb(JCB);printf("\n输入区域名(作业名):");scanf("%s",&q->name);p=as;while(p!=NULL){if(strcmp(p->name,q->name)==0)/*在已分配作业队列中寻找*/{q->addr=p->addr;q->size=p->size;has=1;/*输入作业名存在标志位*/if(p==as)as=p->link;/*在已分配作业队列中删除该作业*/else{k=as;while(k->link!=p)k=k->link;k->link=k->link->link;/*删除*/}printf("输出该作业首地址:%d\n",q->addr);printf("输出该作业大小:%d\n\n",q->size);q->link=NULL;break;}else{p=p->link;has=0;}/*输入作业名不存在标志*/}if(has==0){printf("\n输入作业名错误!请重新输入!\n");input2();}}voidprint(){printf("\n\n\n\n");printf("\t\t**************************************\n");printf("\t\t\t三.存储管理实验演示\n");printf("\t\t**************************************\n\n\n");printf("\t\t\t\t123456\n");printf("\t\t\t\t信自学院\n");printf("\t\t\t\t计专本121\n");printf("\t\t\t\t2012461119\n");printf("\t\t\t\t2013年5月\n");printf("\n\n\n");printf("\t\t\t按任意键进入演示");getch();system("cls");}voidinit_sub()/*初始化空闲分区表*/{r=getsub(SUB);strcpy(r->name,"0");r->addr=5;r->size=10;r->state='F';sub=r;s=getsub(SUB);strcpy(s->name,"1");s->addr=20;s->size=120;s->state='F';sub->link=s;r=s;s=getsub(SUB);strcpy(s->name,"2");s->addr=160;s->size=40;s->state='F';r->link=s;r=s;s=getsub(SUB);strcpy(s->name,"3");s->addr=220;s->size=10;s->state='F';r->link=s;r=s;s=getsub(SUB);strcpy(s->name,"4");s->addr=250;s->size=20;s->state='F';r->link=s;r=s;s=getsub(SUB);strcpy(s->name,"5");s->addr=300;s->size=80;s->state='F';r->link=s;s->link=0;}//--------------------------------------------------------------------------voiddisp()/*空闲分区表的显示函数*/{printf("\n\n");printf("\t\t分区首地址长度状态\n");r=sub;while(r!=NULL){printf("\t\t%s\t\t%d\t\t%d\t\t%c\n",r->name,r->addr,r->size,r->state);r=r->link;}printf("\n");}voiddisp2()/*显示已分配内存的作业表函数*/{printf("\n\n");printf("\t\t作业名首地址长度状态\n");p=as;while(p!=NULL){printf("\t\t%s\t\t%d\t\t%d\t\t%c\n",p->name,p->addr,p->size,p->state);p=p->link;}printf("\n\n");}voidassign2(JCB*pr)/*首次适应作业分区*/{SUB*k;r=sub;/*从空闲表头开始寻找*/while(r!=NULL){if(((r->size)>(pr->size))&&(r->state=='F'))/*有空闲分区大于作业大小的情况*/{pr->addr=r->addr;r->size-=pr->size;r->addr+=pr->size;flag=1;/*分配成功标志位置1*/q=pr;q->state='r';sort3();/*插入已分配作业队列*/printf("作业%s的分区为[%s],首地址为%d.\n",p->name,r->name,pr->addr);break;}elseif(((r->size)==(pr->size))&&(r->state=='F'))/*有空闲分区等于作业大小的情况*/{pr->addr=r->addr;flag=1;/*分配成功标志位置1*/q=pr;sort3();/*插入已分配作业队列*/s=sub;/*空闲分区已完成分配,应删除*/while(s->link!=r)s=s->link;s->link=s->link->link;/*删除空闲分区*/printf("作业%s的分区为[%s],首地址为%d.\n",p->name,r->name,pr->addr);break;}else{r=r->link;flag=0;}}if(flag==0)/*作业过大的情况*/{printf("作业%s长度过大,内存不足,分区分配出错!\n",p->name);is=1;}}voidreclaim2(JCB*pr)/*首次适应与循环首次适应区域回收*/{SUB*k;r=sub;while(r!=NULL){if(r->addr==((pr->addr)+(pr->size)))/*回收区域有下邻*/{pr->size+=r->size;s=sub;isdown=1;/*下邻标志位置1*/while(s!=NULL){if(((s->addr)+(s->size))==(pr->addr))/*有下邻又有上邻*/{s->size+=pr->size;k=sub;while(k->link!=r)k=k->link;k->link=k->link->link;isup=1;/*上邻标志位置1*/break;}else{s=s->link;isup=0;}/*上邻标志位置0*/}if(isup==0)/*有下邻无上邻*/{r->addr=pr->addr;r->size=pr->size;}break;}else{r=r->link;isdown=0;}/*下邻标志位置0*/}if(isdown==0)/*区域无下邻*/{s=sub;while(s!=NULL){if(((s->addr)+(s->size))==(pr->addr))/*无下邻但有上邻*/{s->size+=pr->size;isup=1;/*上邻标志位置1*/break;}else{s=s->link;isup=0;}/*上邻标志位置0*/}if(isup==0)/*无下邻且无上邻*/{k=getsub(SUB);/*重新生成一个新的分区结点*/strcpy(k->name,pr->name);k->addr=pr->addr;k->size=pr->size;k->state='n';r=sub;while(r!=NULL){if((r->addr)>(k->addr))/*按分区首地址排列,回收区域插在合适的位置*/{if(r==sub)/*第一个空闲分区首址大于回收区域的情况*/{k->link=r;sub->link=k;}else{s=sub;while(s->link!=r)s=s->link;k->link=r;s->link=k;}break;}elser=r->link;}if(r==NULL)/*所有空闲分区的首址都大于回收区域首址的情况*/{s=sub;while(s->link!=NULL)s=s->link;s->link=k;k->link=NULL;}}}printf("\n区域%s己回收.",pr->name);}menu(){printf("\n\n\n\t\t**************************************\n");printf("\t\t\t存储管理实验演示\n");printf("\t\t**************************************\n\n\n");printf("\t\t\t1.显示空闲分区\n");printf("\t\t\t2.分配和回收作业\n");printf("\t\t\t0.退出\n");printf("\t\t\t请选择你要的操作:");switch(getchar()){case'1':system("cls");disp();getch();system("cls");menu();break;case'2':system("cls");printf("\n首次适应算法");input();printf("\n");while(num!=0){p=ready;ready=p->link;p->link=NULL;assign2(p);num--;}printf("\n显示回收后的空闲分区表和已分配作业表...");getch();printf("\n\t\t完成分配后的空闲分区表\n");disp();printf("\n\t\t已分配作业表\n");disp2();if(is==0)printf("\n全部作业已经被分配内存.");elseprintf("\n作业没有全部被分配内存.\n");printf("\n\n按任意键进行区域回收.");printf("\n");while(as!=NULL){getch();input2();printf("按任意键继续...");getch();printf("\n");reclaim2(q);printf("\n显示回收后的空闲分区表和已分配作业表...");getch();printf("\n\t\t回收后的空闲分区表\n");disp();printf("\n\t\t已分配作业表\n");disp2();printf("\n继续回收...(Enter)");}printf("\n所有已分配作业已完成!");printf("\nPressanykeytoreturn...");getch();system("cls");menu();break;case'0':system("cls");break;default:system("cls");menu();}}voidmain()/*主函数*/{init_sub();print();menu();}
printf("\n作业号No.%d:
\n",i);
p=getjcb(JCB);
printf("\n输入作业名:
scanf("%s",&p->name);
printf("\n输入作业的大小:
scanf("%d",&p->size);
printf("\n输入作业所需运行时间:
scanf("%d",&p->ntime);
p->state='w';
sort();/*调用sort函数*/
printf("\n按任一键继续......\n");
getch();
voidinput2()/*建立要回收区域的函数*/
JCB*k;
inthas;
q=getjcb(JCB);
printf("\n输入区域名(作业名):
scanf("%s",&q->name);
p=as;
while(p!
{if(strcmp(p->name,q->name)==0)/*在已分配作业队列中寻找*/
q->addr=p->addr;
q->size=p->size;
has=1;/*输入作业名存在标志位*/
if(p==as)as=p->link;/*在已分配作业队列中删除该作业*/
else
{k=as;
while(k->link!
=p)k=k->link;
k->link=k->link->link;/*删除*/
printf("输出该作业首地址:
%d\n",q->addr);
printf("输出该作业大小:
%d\n\n",q->size);
break;
{p=p->link;has=0;}/*输入作业名不存在标志*/
if(has==0)
{printf("\n输入作业名错误!
请重新输入!
\n");
input2();
voidprint()
{printf("\n\n\n\n");
printf("\t\t**************************************\n");
printf("\t\t\t三.存储管理实验演示\n");
printf("\t\t**************************************\n\n\n");
printf("\t\t\t\t123456\n");
printf("\t\t\t\t信自学院\n");
printf("\t\t\t\t计专本121\n");
printf("\t\t\t\t2012461119\n");
printf("\t\t\t\t2013年5月\n");
printf("\n\n\n");
printf("\t\t\t按任意键进入演示");
system("cls");
voidinit_sub()/*初始化空闲分区表*/
r=getsub(SUB);
strcpy(r->name,"0");r->addr=5;r->size=10;r->state='F';
sub=r;
s=getsub(SUB);
strcpy(s->name,"1");s->addr=20;s->size=120;s->state='F';
sub->link=s;r=s;
strcpy(s->name,"2");s->addr=160;s->size=40;s->state='F';
r->link=s;r=s;
strcpy(s->name,"3");s->addr=220;s->size=10;s->state='F';
strcpy(s->name,"4");s->addr=250;s->size=20;s->state='F';
strcpy(s->name,"5");s->addr=300;s->size=80;s->state='F';
r->link=s;
s->link=0;
//--------------------------------------------------------------------------
voiddisp()/*空闲分区表的显示函数*/
printf("\n\n");
printf("\t\t分区首地址长度状态\n");
r=sub;
while(r!
printf("\t\t%s\t\t%d\t\t%d\t\t%c\n",r->name,r->addr,r->size,r->state);
r=r->link;
printf("\n");
voiddisp2()/*显示已分配内存的作业表函数*/
printf("\t\t作业名首地址长度状态\n");
printf("\t\t%s\t\t%d\t\t%d\t\t%c\n",p->name,p->addr,p->size,p->state);
p=p->link;
voidassign2(JCB*pr)/*首次适应作业分区*/
SUB*k;
r=sub;/*从空闲表头开始寻找*/
if(((r->size)>(pr->size))&&(r->state=='F'))/*有空闲分区大于作业大小的情况*/
pr->addr=r->addr;
r->size-=pr->size;
r->addr+=pr->size;
flag=1;/*分配成功标志位置1*/
q=pr;
q->state='r';
sort3();/*插入已分配作业队列*/
printf("作业%s的分区为[%s],首地址为%d.\n",p->name,r->name,pr->addr);
elseif(((r->size)==(pr->size))&&(r->state=='F'))/*有空闲分区等于作业大小的情况*/
s=sub;/*空闲分区已完成分配,应删除*/
while(s->link!
=r)s=s->link;
s->link=s->link->link;/*删除空闲分区*/
{r=r->link;flag=0;}
if(flag==0)/*作业过大的情况*/
printf("作业%s长度过大,内存不足,分区分配出错!
\n",p->name);
is=1;
voidreclaim2(JCB*pr)/*首次适应与循环首次适应区域回收*/
if(r->addr==((pr->addr)+(pr->size)))/*回收区域有下邻*/
pr->size+=r->size;
s=sub;
isdown=1;/*下邻标志位置1*/
while(s!
if(((s->addr)+(s->size))==(pr->addr))/*有下邻又有上邻*/
s->size+=pr->size;
k=sub;
=r)k=k->link;
k->link=k->link->link;
isup=1;/*上邻标志位置1*/
{s=s->link;isup=0;}/*上邻标志位置0*/
if(isup==0)/*有下邻无上邻*/
r->addr=pr->addr;
r->size=pr->size;
{r=r->link;isdown=0;}/*下邻标志位置0*/
if(isdown==0)/*区域无下邻*/
if(((s->addr)+(s->size))==(pr->addr))/*无下邻但有上邻*/
if(isup==0)/*无下邻且无上邻*/
k=getsub(SUB);/*重新生成一个新的分区结点*/
strcpy(k->name,pr->name);
k->addr=pr->addr;
k->size=pr->size;
k->state='n';
if((r->addr)>(k->addr))/*按分区首地址排列,回收区域插在合适的位置*/
if(r==sub)/*第一个空闲分区首址大于回收区域的情况*/
{k->link=r;sub->link=k;}
k->link=r;
s->link=k;
elser=r->link;
if(r==NULL)/*所有空闲分区的首址都大于回收区域首址的情况*/
=NULL)s=s->link;
k->link=NULL;
printf("\n区域%s己回收.",pr->name);
menu()
printf("\n\n\n\t\t**************************************\n");
printf("\t\t\t存储管理实验演示\n");
printf("\t\t\t1.显示空闲分区\n");
printf("\t\t\t2.分配和回收作业\n");
printf("\t\t\t0.退出\n");
printf("\t\t\t请选择你要的操作:
switch(getchar())
case'1':
disp();
menu();
case'2':
printf("\n首次适应算法");
input();
while(num!
=0)
p=ready;
ready=p->link;
assign2(p);
num--;
printf("\n显示回收后的空闲分区表和已分配作业表...");
printf("\n\t\t完成分配后的空闲分区表\n");
printf("\n\t\t已分配作业表\n");
disp2();
if(is==0)
printf("\n全部作业已经被分配内存.");
elseprintf("\n作业没有全部被分配内存.\n");
printf("\n\n按任意键进行区域回收.");
while(as!
{getch();
printf("按任意键继续...");
reclaim2(q);
printf("\n\t\t回收后的空闲分区表\n");
printf("\n继续回收...(Enter)");
printf("\n所有已分配作业已完成!
printf("\nPressanykeytoreturn...");
case'0':
default:
voidmain()/*主函数*/
init_sub();
print();
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1