实验感想:
通过本实验,我进一步掌握进了程调度的功能和实现原理。熟练掌握了两种进程调度算法的应用,相信这对以后进一步学习操作系统、信息系统的开发都有很大的好处。
实验三:模拟动态分区首次适应分配和回收算法
实验目的:
通过本实验,可加深理解动态分区分配、回收程序的功能和具体实现,特别是对回收分区的合并的理解。
实验内容:
1、 设计动态分区首次适应分配、回收算法。 2、 设计“未分配区说明表”,格式为:
序号 1 始址 60k 长度 200 状态 1 0 3、设计“已分配区说明表”,格式为:
作业名 始址 长度 状态 0 0 4、 设计显示程序,将“未分配区说明表”和“已分配区说明表”的内容,显示在屏幕上。 初始分配从一个空闲区分配起,回收时要合并空区。
实验步骤:
1、 系统要求分配一个分区时,应输入:作业名、作业长度。
2、
回收一个分区时,应输入:回收的作业名。回收的分区请注意是否需要进行合并。
21
实验代码:
#include
int MAX_SEGMENT=10;//最大碎片值 struct Partition //分区表目 { int Par_Size; //分区大小 int Par_No; //分区序号或者名字 int Addr; //分区地址
int IsUse;
//分区使用情况,0表示空闲,1表示使用
Partition *pri; //前向指针
Partition *next;
//后向指针
};
Partition * Int()//函数,返回Partition类型指针 { //初始化空闲分区表 Partition *list,*H,*H1;
list=(struct Partition *)malloc(sizeof(struct Partition));//malloc申请动态分配空间 list->next=NULL;
H=list; if(!list) { printf(\错误,内存初始化分配失败!程序结束\
exit(1);
}
H1=(struct Partition *)malloc(sizeof(struct Partition)); printf(\请预先输入分区总大小(以KB为单位):\ scanf(\
H1->Addr=0; H1->Par_No=0; H1->IsUse=0; H1->pri=H;
H1->next=NULL;
H->next=H1;////list--->H1 return list; }
Partition * InitFP() { //初始化已分配分区表 Partition *FP,*F,*H; int i;
FP=(struct Partition *)malloc(sizeof(struct Partition)); FP->next=NULL;
H=FP;
22
}
for(i=0;i<10;i++) {
//已分配区先暂定分配十个表目
F=(struct Partition *)malloc(sizeof(struct Partition)); if(!F) { printf(\错误,内存分配失败!程序结束\
exit(1); }
F->Par_Size=0; F->Addr=0; F->Par_No=0; F->IsUse=0; F->next=NULL; H->next=F; F->pri=H; H=H->next;
}
return FP;
Partition * New_Process( Partition *list, Partition *FP) { //为新的进程分配资源
Partition *H,*P,*H1; int Size,Name,L; H=list;
H1=FP->next;
H=H->next;
printf(\请输入新作业的名称和大小(整数)\\n\printf(\作业名称:\scanf(\
printf(\作业大小(整数):\scanf(\while(H) {
if(!H) {
//表目已查完,无法分配
printf(\已无空闲分区,本次无法分配!\return list;
} else{ if(H->IsUse==0) //if(H->Par_Size>=Size)
if(H->Par_Size>=Size) {
bool temp=false;
//空表目
//大小满足,空闲分区大小》要分配的大小 //大小满足,
23
if((H->Par_Size-Size)<=MAX_SEGMENT){//空闲分区大小-要分配的
大小<碎片值,会产生碎片,将整块内存大小分配出去, Size=H->Par_Size;//分配的大小为整块内存 temp=true;//会产生碎片
}
//其他情况就分配大小为请求大小,不会产生碎片, L=H->Addr;//保存空闲分地址
if(temp){ printf(\该次内存分配会产生碎片,将整块内存大小%d分配出}else{ printf(\该次内存分配不会产生碎片\ } break;
去!\
} }
H=H->next;
//否则,继续往下查找
} if(H) {
if(H->Par_Size>Size)
//大小满足,空闲分区大小》要分配的大小
//分配新的表目,
{ P=(struct Partition *)malloc(sizeof(struct Partition)); 处理一条数据,分配一次内存
P->IsUse=1;
P->Addr=L;//指向空闲分区地址 P->next=H; //修改指针
H->pri->next=P; P->pri=H->pri; H->pri=P;
P->Par_Size=Size;//分配大小为要请求分配的大小 P->Par_No=Name;//名称
H->Par_Size-=Size; //修改空闲分区,H所指区块大小减Size H->Addr+=Size;//H所指区块地址加Size
}else { H->IsUse=1; }
while(H1) {
if(H1->IsUse==0) {
//大小相等的,把当前表项设置空表目
H1->Par_No=Name; H1->Par_Size=Size;
24
H1->Addr=L;//保存已分配地址
H1->IsUse=1;//在已分配表中设置为已分配
break; }
H1=H1->next;
}
}else printf(\所申请资源已大过系统所拥有的,请重新输入!\\n\ return list;
}
Partition *Reclaim( Partition *list, Partition *FP) { //结束作业,资源回收,No为作业名,回收内存
Partition * H1,*H2,*H3,*HF;//H1为释放区,H2为后分区,H3为前分区 int No; //作业名 H1=list;
HF=FP;//可有可无?
H1=H1->next; HF=FP->next;
printf(\请输入您想结束的作业名:\ scanf(\
while(HF)//对已分配表进行操作 { if(HF->Par_No==No) { HF->IsUse=0; //标志为空表目 break;//这时保存着HF所指分区的信息
}
HF=HF->next; }
if(!HF) //如果找不到该作业,则提示出错
printf(\所输入的作业名称不正确,请重新输入!\ else{ while(H1)//对空闲表进行操作 { if(H1->Par_No==No) { H1->IsUse=0; //标志为空表目 printf(\内存回收成功\ break;
}
H1=H1->next;
}
H2=H1->next;//后分区
H3=H1->pri;//前分区
25