printf("%s%d%d\n",pcb1[j].name,pcb1[j].priority,pcb1[j].runtime);
}
}
}
程序运行结果
实训小结:
通过设计并调试创建、终止、阻塞、唤醒原语功能,加深了对操作系统中进程控制功能的理解,并且掌握操作系统模块的设计方法和工作原理。
更重要的是理解了操作系统的调度方法是就绪-运行-堵塞-唤醒-结束的过程。
实训二:
模拟动态分区首次适应分配和回收算法
实训目的:
通过本实训,可加深理解动态分区分配、回收程序的功能和具体实现,特别是对回收分区的合并的理解。
实训内容:
1、设计动态分区首次适应分配、回收算法。
2、设计“未分配区说明表”,格式为:
序号
始址
长度
状态
1
60k
200
1
0
3、设计“已分配区说明表”,格式为:
作业名
始址
长度
状态
0
0
4、设计显示程序,将“未分配区说明表”和“已分配区说明表”的内容显示在屏幕上。
初始分配从一个空闲区分配起,回收时要合并空区。
实训步骤:
1、系统要求分配一个分区时,应输入:
作业名、作业长度。
2、回收一个分区时,应输入:
回收的作业名。
回收的分区请注意是否需要进行合并。
实训代码:
#include
#include
intMAX_SEGMENT=10;//最大碎片值
structPartition//分区表目
{
intPar_Size;//分区大小
intPar_No;//分区序号或者名字
intAddr;//分区地址
intIsUse;//分区使用情况,0表示空闲,1表示使用
Partition*pri;//前向指针
Partition*next;//后向指针
};
Partition*Int()//函数,返回Partition类型指针
{
//初始化空闲分区表
Partition*list,*H,*H1;
list=(structPartition*)malloc(sizeof(structPartition));//malloc申请动态分配空间
list->next=NULL;
H=list;
if(!
list)
{
printf("\n错误,内存初始化分配失败!
程序结束");
exit
(1);
}
H1=(structPartition*)malloc(sizeof(structPartition));
printf("请预先输入分区总大小(以KB为单位):
");
scanf("%d",&H1->Par_Size);
H1->Addr=0;
H1->Par_No=0;
H1->IsUse=0;
H1->pri=H;
H1->next=NULL;
H->next=H1;////list--->H1
returnlist;
}
Partition*InitFP()
{//初始化已分配分区表
Partition*FP,*F,*H;
inti;
FP=(structPartition*)malloc(sizeof(structPartition));
FP->next=NULL;
H=FP;
for(i=0;i<10;i++)//已分配区先暂定分配十个表目
{
F=(structPartition*)malloc(sizeof(structPartition));
if(!
F)
{
printf("\n错误,内存分配失败!
程序结束");
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;
}
returnFP;
}
Partition*New_Process(Partition*list,Partition*FP)
{
//为新的进程分配资源
Partition*H,*P,*H1;
intSize,Name,L;
H=list;
H1=FP->next;
H=H->next;
printf("请输入新作业的名称和大小(整数)\n");
printf("作业名称:
");
scanf("%d",&Name);
printf("作业大小(整数):
");
scanf("%d",&Size);
while(H)
{
if(!
H)//表目已查完,无法分配
{
printf("\n已无空闲分区,本次无法分配!
");
returnlist;
}
else{
if(H->IsUse==0)//空表目
//if(H->Par_Size>=Size)//大小满足,空闲分区大小》要分配的大小
if(H->Par_Size>=Size)//大小满足,
{
booltemp=false;
//空闲分区大小-要分配的大小<碎片值
//会产生碎片,将整块内存大小分配出去,
if((H->Par_Size-Size)<=MAX_SEGMENT){Size=H->Par_Size;//分配的大小为整块内存
temp=true;//会产生碎片
}
//其他情况就分配大小为请求大小,不会产生碎片,
L=H->Addr;//保存空闲分地址
if(temp)
printf("该次分配会产生碎片,大小为%d的内存分配出去!
",Size);
else
printf("该次内存分配不会产生碎片");
break;
}
}
H=H->next;//否则,继续往下查找
}
if(H)
{
if(H->Par_Size>Size)//大小满足,空闲分区大小》要分配的大小
{
//分配新的表目,处理一条数据,分配一次内存
P=(structPartition*)malloc(sizeof(structPartition));
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;
H1->Addr=L;//保存已分配地址
H1->IsUse=1;//在已分配表中设置为已分配
break;
}
H1=H1->next;
}
}else
printf("所申请资源已大过系统所拥有的,请重新输入!
\n");
returnlist;
}
Partition*Reclaim(Partition*list,Partition*FP)
{
//结束作业,资源回收,No为作业名,回收内存
Partition*H1,*H2,*H3,*HF;//H1为释放区,H2为后分区,H3为前分区
intNo;//作业名
H1=list;
HF=FP;//可有可无?
H1=H1->next;
HF=FP->next;
printf("请输入您想结束的作业名:
");
scanf("%D",&No);
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;//前分区
if(H2&&H2->IsUse==0)//后接分区为空闲
{
if(H2->next==NULL)//判断后接分区是否为尾结点
{
H1->Par_Size+=H2->Par_Size;//把H2合并到H1
H1->next=NULL;
free(H2);
printf("已回收%d大小内存",H1->Par_Size);
}
else//后分区不为空闲,表示已经被使用
{
H1->Par_Size+=H2->Par_Size;
H1->next=H2->next;
H2->next->pri=H1;
free(H2);
printf("已回收%d大小内存",H1->Par_Size);
}
}
if(H3&&H3->IsUse==0)//前分区为空闲分区,则合并去前分区
{
H3->Par_Size+=H1->Par_Size;
H3->next=H1->next;
if(H1->next!
=NULL)//若H1为尾结点
H1->next->pri=H3;
free(H1);
printf("已回收%d大小内存",H1->Par_Size);
}
}
returnlist;
}
voidPrint(Partition*list,Partition*FP)
{
//输出已分配分区和空闲分区
Partition*H1,*H2;
H1=list->next;
H2=FP;
H2=H2->next;
printf("**************************************************\n");
printf("****************总分配分区表*******************\n");
printf("分区序号大小开始地址状态\n");
while(H1)
{
printf("%d%d%d",H1->Par_No,H1->Par_Size,H1->Addr);
if(H1->IsUse==1)
printf("已分配\n");
else
printf("空表目\n");
H1=H1->next;
}
printf("**************************************************\n");
}
voidMain_Print(Partition*list,Partition*FP)
{
//程序主入口函数,进行菜单选择
intop;
while
(1)
{
printf("\n--------------------------主菜单------------------------\n");
printf("\n");
printf("1.申请新的作业,分配内存\n");
printf("2.结束作业,回收内存\n");
printf("3.查看内存表\n");
printf("4.退出系统\n");
printf("\n请选择<1-4>:
");
scanf("%d",&op);
switch(op)//根据输入,选择分支方向
{
case1:
New_Process(list,FP);
break;
case2:
Reclaim(list,FP