第十周固定分区分配管理实验.docx
《第十周固定分区分配管理实验.docx》由会员分享,可在线阅读,更多相关《第十周固定分区分配管理实验.docx(19页珍藏版)》请在冰点文库上搜索。
![第十周固定分区分配管理实验.docx](https://file1.bingdoc.com/fileroot1/2023-5/14/1fe5bbb4-e520-4d64-8e24-6516a859c540/1fe5bbb4-e520-4d64-8e24-6516a859c5401.gif)
第十周固定分区分配管理实验
存储管理实验实验报告
1实验目的
设计一个固定分区分配的存储管理方案,并编程模拟实现分区的分配和回收过程。
对分区的管理法可以是循环首次适应算法或最佳适应算法。
2实验原理
通过采用最佳适应算法的固定式分区分配的存储管理方案,模拟实现分区的分配和回收过程。
可以假定每个作业都是批处理作业,并且不允许动态申请内存。
为实现分区的分配和回收,可以设定一个分区说明表,按照表中的有关信息进行分配,并根据分区的分配和回收情况修改该表。
3采用算法及算法描述
本程序通过手动输入内存大小的输入,然后通过冒泡法对分区的大小进行排序,采用最佳适应算法构建整个算法的架构,该算法要求所有的空闲分区按照其容量的大小进行从小到大的顺序形成一空闲分区链。
因而,第一次如果能够满足要求的空闲区,必然是最佳的。
该算法也存在一定的缺陷,因为每次分配后切割下来的剩余部分总是最小的,故而存储器中会留下许多难以利用的小空余区。
4数据结构描述,程序模块划分
头文件模块:
#include"stdio.h"
#include"windows.h"
#include
#include
#definePCB_NUM5//模拟进程数量
#defineINT800//内存分区数量
structMemInf{
intaddr;//分区起始地址
intsize;//分区大小
intstate;//0表示空闲,>0时表示已分配,存储的是进程ID
};
structPCB{
intpcbID;//进程ID
intsize;//进程大小
intRunState;//运行状态,0表示就绪,1表示已分配内存正运行,2表示运行结束且退出内存
intTolTime;//总需要运行时间
intRunTime;//已运行时间
};
PCBpcbList[PCB_NUM];
菜单模块:
voidmenu()//菜单
{
intm;
system("cls");
printf("\n\n\t\t*********************************************\t\t\n");
printf("\t\t\t\t固定分区存储程序演示\n");
printf("\t\t*********************************************\t\t\n");
printf("\n\t\t\t1.执行程序.");
printf("\n\t\t\t0.退出程序.");
scanf("%d",&m);
switch(m)
{case1:
break;
case0:
system("cls");
menu();
break;
default:
system("cls");
break;
}
}
排序模块:
voidpaixu(structMemInf*ComMem,intn)
{
inti,j,t;
for(j=0;jfor(i=0;iif(ComMem[i].size>ComMem[i+1].size)
{
t=ComMem[i].size;
ComMem[i].size=ComMem[i+1].size;
ComMem[i+1].size=t;
}
}
voidpaixu2()
{
inti,j,t;
for(j=0;j<4;j++)
for(i=0;i<4-j;i++)
if(pcbList[i].size>pcbList[i+1].size)
{
t=pcbList[i].size;
pcbList[i].size=pcbList[i+1].size;
pcbList[i+1].size=t;
}
}
主函数模块:
voidmain()
{
DD:
menu();
charch;
inti,j,n,a=0;
structMemInf*ComMem;
system("cls");
printf("你要分多少个分区呢,请输入数值吧:
");//个分区大小的输入
scanf("%d",&n);
ComMem=(structMemInf*)malloc(n*sizeof(structMemInf));
printf("请划分内存固定大小分区:
\n");//划分内存固定大小分区
for(i=0;i{
printf("输入固定分区%d分区的长度:
",i);//输入固定分区每个的长度
scanf("%d",&ComMem[i].size);
if(i==0)ComMem[i].addr=40;//定义第一个分区的起始地址为40
elseComMem[i].addr=ComMem[i-1].addr+ComMem[i-1].size;//表示下一个起始地址的起始状态表示的是分区长度加上起始地址长度
ComMem[i].state=0;//表示状态为未分配
a=ComMem[i].size+a;
if(a>=INT)
{
printf("超出规定内存范围");
ch=getchar();
ch=getchar();
gotoDD;
}
}
paixu(ComMem,n);
//初始化就绪进程队列
pcbList[0].pcbID=1;
pcbList[0].RunState=0;//运行状态,0表示就绪,1表示已分配内存正运行,2表示运行结束且退出内存
pcbList[0].size=30;
pcbList[0].RunTime=0;
pcbList[0].TolTime=5;
pcbList[1].pcbID=2;
pcbList[1].RunState=0;
pcbList[1].size=15;
pcbList[1].RunTime=0;
pcbList[1].TolTime=6;
pcbList[2].pcbID=3;
pcbList[2].RunState=0;
pcbList[2].size=50;
pcbList[2].RunTime=0;
pcbList[2].TolTime=3;
pcbList[3].pcbID=4;
pcbList[3].RunState=0;
pcbList[3].size=120;
pcbList[3].RunTime=0;
pcbList[3].TolTime=4;
pcbList[4].pcbID=5;
pcbList[4].RunState=0;
pcbList[4].size=125;
pcbList[4].RunTime=0;
pcbList[4].TolTime=9;
ch=getchar();
ch=getchar();
while(pcbList[PCB_NUM-1].RunTime{
{
for(j=0;j{
//内存分配
for(i=0;i{
if(ComMem[i].state==0&&pcbList[j].RunState==0)//内存分区为0空闲,且进程状态为就绪,即可以考虑分配该内存分区
if(ComMem[i].size>=pcbList[j].size)//如果该内存分区空间大于或等于进程空间,即可以把该空闲内存分区分配给该进程
{ComMem[i].state=pcbList[j].pcbID;
pcbList[j].RunState=1;
}
}
//内存回收
if(pcbList[j].RunTime>=pcbList[j].TolTime)//如果该进程运行时间大于或等于总需时间,即可回收该进程占用内存
for(i=0;iif(ComMem[i].state==pcbList[j].pcbID)
{ComMem[i].state=0;//内存状态变为"未分配"
pcbList[j].RunState=2;//进程状态变为"运行完毕"
}
//运行时间加1
for(i=0;iif(pcbList[i].RunState==1&&pcbList[i].RunTimepcbList[i].RunTime++;
显示模块:
printf("进程ID\t进程大小\t状态\t需要时间\t运行时间\n");
for(i=0;iprintf("%d\t%d\t\t%d\t%d\t\t%d\n",pcbList[i].pcbID,pcbList[i].size,pcbList[i].RunState,pcbList[i].TolTime,pcbList[i].RunTime);
printf("分区ID\t分区大小\t状态\n");
for(i=0;iprintf("%d\t%d\t\t%d\n",i,ComMem[i].size,ComMem[i].state);
printf("按回车键继续...\n");getchar();//按任意键继续(分步执行,以便观察内存分配回收)
}
}
5主模块流程图、各子模块流程图
6程序源代码及调试
#include"stdio.h"
#include"windows.h"
#include
#include
#definePCB_NUM5//模拟进程数量
#defineINT800//内存分区数量
structMemInf{
intaddr;//分区起始地址
intsize;//分区大小
intstate;//0表示空闲,>0时表示已分配,存储的是进程ID
};
structPCB{
intpcbID;//进程ID
intsize;//进程大小
intRunState;//运行状态,0表示就绪,1表示已分配内存正运行,2表示运行结束且退出内存
intTolTime;//总需要运行时间
intRunTime;//已运行时间
};
PCBpcbList[PCB_NUM];
voidmenu()//菜单
{
intm;
system("cls");
printf("\n\n\t\t*********************************************\t\t\n");
printf("\t\t\t\t固定分区存储程序演示\n");
printf("\t\t*********************************************\t\t\n");
printf("\n\t\t\t1.执行程序.");
printf("\n\t\t\t0.退出程序.");
scanf("%d",&m);
switch(m)
{case1:
break;
case0:
system("cls");
menu();
break;
default:
system("cls");
break;
}
}
voidpaixu(structMemInf*ComMem,intn)
{
inti,j,t;
for(j=0;jfor(i=0;iif(ComMem[i].size>ComMem[i+1].size)
{
t=ComMem[i].size;
ComMem[i].size=ComMem[i+1].size;
ComMem[i+1].size=t;
}
}
voidpaixu2()
{
inti,j,t;
for(j=0;j<4;j++)
for(i=0;i<4-j;i++)
if(pcbList[i].size>pcbList[i+1].size)
{
t=pcbList[i].size;
pcbList[i].size=pcbList[i+1].size;
pcbList[i+1].size=t;
}
}
voidmain()
{
DD:
menu();
charch;
inti,j,n,a=0;
structMemInf*ComMem;
system("cls");
printf("你要分多少个分区呢,请输入数值吧:
");
scanf("%d",&n);
ComMem=(structMemInf*)malloc(n*sizeof(structMemInf));
printf("请划分内存固定大小分区:
\n");//划分内存固定大小分区
for(i=0;i{
printf("输入固定分区%d分区的长度:
",i);//输入固定分区每个的长度
scanf("%d",&ComMem[i].size);
if(i==0)ComMem[i].addr=40;//定义第一个分区的起始地址为40
elseComMem[i].addr=ComMem[i-1].addr+ComMem[i-1].size;//表示下一个起始地址的起始状态表示的是分区长度加上起始地址长度
ComMem[i].state=0;//表示状态为未分配
a=ComMem[i].size+a;
if(a>=INT)
{
printf("超出规定内存范围");
ch=getchar();
ch=getchar();
gotoDD;
}
}
paixu(ComMem,n);
//初始化就绪进程队列
pcbList[0].pcbID=1;
pcbList[0].RunState=0;//运行状态,0表示就绪,1表示已分配内存正运行,2表示运行结束且退出内存
pcbList[0].size=30;
pcbList[0].RunTime=0;
pcbList[0].TolTime=5;
pcbList[1].pcbID=2;
pcbList[1].RunState=0;
pcbList[1].size=15;
pcbList[1].RunTime=0;
pcbList[1].TolTime=6;
pcbList[2].pcbID=3;
pcbList[2].RunState=0;
pcbList[2].size=50;
pcbList[2].RunTime=0;
pcbList[2].TolTime=3;
pcbList[3].pcbID=4;
pcbList[3].RunState=0;
pcbList[3].size=120;
pcbList[3].RunTime=0;
pcbList[3].TolTime=4;
pcbList[4].pcbID=5;
pcbList[4].RunState=0;
pcbList[4].size=125;
pcbList[4].RunTime=0;
pcbList[4].TolTime=9;
ch=getchar();
ch=getchar();
while(pcbList[PCB_NUM-1].RunTime{
{
for(j=0;j{
//内存分配
for(i=0;i{
if(ComMem[i].state==0&&pcbList[j].RunState==0)//内存分区为0空闲,且进程状态为就绪,即可以考虑分配该内存分区
if(ComMem[i].size>=pcbList[j].size)//如果该内存分区空间大于或等于进程空间,即可以把该空闲内存分区分配给该进程
{ComMem[i].state=pcbList[j].pcbID;
pcbList[j].RunState=1;
}
}
//内存回收
if(pcbList[j].RunTime>=pcbList[j].TolTime)//如果该进程运行时间大于或等于总需时间,即可回收该进程占用内存
for(i=0;iif(ComMem[i].state==pcbList[j].pcbID)
{ComMem[i].state=0;//内存状态变为"未分配"
pcbList[j].RunState=2;//进程状态变为"运行完毕"
}
//运行时间加1
for(i=0;iif(pcbList[i].RunState==1&&pcbList[i].RunTimepcbList[i].RunTime++;
//显示模块
printf("进程ID\t进程大小\t状态\t需要时间\t运行时间\n");
for(i=0;iprintf("%d\t%d\t\t%d\t%d\t\t%d\n",pcbList[i].pcbID,pcbList[i].size,pcbList[i].RunState,pcbList[i].TolTime,pcbList[i].RunTime);
printf("分区ID\t分区大小\t状态\n");
for(i=0;iprintf("%d\t%d\t\t%d\n",i,ComMem[i].size,ComMem[i].state);
printf("按回车键继续...\n");getchar();//按任意键继续(分步执行,以便观察内存分配回收)
}
}
}
}
7程序运行调试和结果
8实验体会
实践是检验知识过不过关的关键,通过对该实验的操作,我们发现了许多之前的问题,但是我们组积极分工进行操作,通过连续奋斗,终于基本掌握了整个程序的运行原理与增强了对最佳适应算法的理解,同时更进一步认识了操作系统,更重要的是我们认识到了团地精神的重要性。