操作系统实验四主存空间的分配回收首次适应算法和循环首次适应算法.docx
《操作系统实验四主存空间的分配回收首次适应算法和循环首次适应算法.docx》由会员分享,可在线阅读,更多相关《操作系统实验四主存空间的分配回收首次适应算法和循环首次适应算法.docx(17页珍藏版)》请在冰豆网上搜索。
![操作系统实验四主存空间的分配回收首次适应算法和循环首次适应算法.docx](https://file1.bdocx.com/fileroot1/2023-3/1/c2734028-b574-4d51-86c6-177eaec5ecea/c2734028-b574-4d51-86c6-177eaec5ecea1.gif)
操作系统实验四主存空间的分配回收首次适应算法和循环首次适应算法
实验报告
【实验名称】首次适应算法和循环首次适应算法
【实验目的】
理解在连续分区动态的存储管理方式下,如何实现主存空间的分配与回收。
【实验原理】
首次适应(firstfit,FF)算法
FF算法要求空闲分区链以地址递增的次序链接。
在分配内存时,从链首开始顺序查找,直至找到一个大小能满足要求的空闲分区即可。
然后再按照作业的大小,从该分区中划出一块内存空间,分配给请求者,余下的空闲分区仍留在空闲链中。
若从链首直至链尾都不能找到一个能满足要求的分区,则表明系统中已经没有足够大的内存分配给该进程,内存分配失败,返回。
循环首次适应(nextfit,NF)算法
为避免低址部分留下许多很小的空闲分区,以及减少查找可用空闲分区的开销,循环首次适应算法在为进程分配内存空间时,不再是每次都从链首开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,直至找到一个能满足要求的空闲分区,从中划出一块玉请求大小相等的内存空间分配给作业。
【实验内容】
实现主存空间的分配与回收:
1.采用可变式分区管理,使用首次适应算法实现主存空间的分配与回收;
2.采用可变式分区管理,使用循环首次适应算法实现主存空间的分配与回收。
数据结构和符号说明:
typedefstructPCB//进程控制块
{
charProgressName[10];//进程名称
intStartaddress;//进程开始地址
intProgressSize;//进程大小
intProgressState=0;//进程状态
};
typedefstructFREE//空闲区结构体
{
intFree_num;//空闲区名称
intStartaddress;//空闲区开始地址
intEndaddress;//空闲区结束地址
intFree_Space;//空闲区大小
};
算法流程图:
首次适应算法
循环首次适应算法
程序代码及截图:
#include
#include
#include
#include
#defineN1024
typedefstructPCB//进程控制块
{
charProgressName[10];//进程名称
intStartaddress;//进程开始地址
intProgressSize;//进程大小
intProgressState=0;//进程状态
};
typedefstructFREE//空闲区结构体
{
intFree_num;//空闲区名称
intStartaddress;//空闲区开始地址
intEndaddress;//空闲区结束地址
intFree_Space;//空闲区大小
};
intcount=0;//当前内存中进程个数
boolROM[N];//设置内存块
intp=0;//循环首次使用需要标记当前的空闲区块
FREEFREE[100];//设置空闲区数组为100个
intFREE_counter=0;//空闲区的个数
PCBnum[20];//作业队列
voidinit()//初始化操作
{
for(inti=0;iROM[i]=0;
}
voidshowProgress(PCB&a)
{
printf("----------------------------------------------------------------------\n");
printf("进程名\t\t开始地址\t\t大小\t\t结束地址\n");//输出内存信息
printf("----------------------------------------------------------------------\n");
for(inti=0;ifor(intj=i;jif(num[j].Startaddress>num[j+1].Startaddress)
{
a=num[j];
num[j]=num[j+1];
num[j+1]=a;
}
for(inti=0;iif(num[i].ProgressState!
=0)
printf("%s\t\t%d\t\t\t%d\t\t%d\t\t\n",num[i].ProgressName,num[i].Startaddress,num[i].ProgressSize,num[i].ProgressSize+num[i].Startaddress-1);
printf("----------------------------------------------------------------------\n");
}
voidshowFree()//打印空闲区的情况
{
printf("----------------------------------------------------------------------\n");
printf("空闲区名\t|开始地址\t|大小\t|结束地址\n");
printf("----------------------------------------------------------------------\n");
for(inti=1;i<=FREE_counter;i++)
{
printf("\t%1d\t%8d\t%11d\t%d\n",FREE[i].Free_num,FREE[i].Startaddress,FREE[i].Free_Space,FREE[i].Endaddress);
printf("----------------------------------------------------------------------\n");
}
}
voidfind_FREE()//寻找空闲区
{
inti,j,p;//计数值
FREE_counter=0;//预设空闲区数为0
for(i=0;iif(ROM[i]==0)
{
p=i;
for(j=i;j{
if(ROM[j]==0)//未找到空闲区,则将j赋值给i后继续循环
{
i=j;
continue;
}
if(ROM[j]==1)//找到空闲区
{
FREE_counter++;//空闲区个数+1;
FREE[FREE_counter].Free_num=FREE_counter;//设置空闲区编号
FREE[FREE_counter].Startaddress=p;
FREE[FREE_counter].Endaddress=j-1;
FREE[FREE_counter].Free_Space=j-p;
i=j+1;
break;
}
}
if(j==N&&ROM[j-1]==0)//对最后一个内存进行特殊操作
{
FREE_counter++;
FREE[FREE_counter].Free_num=FREE_counter;//对空闲区进行处理
FREE[FREE_counter].Startaddress=p;
FREE[FREE_counter].Endaddress=j-1;
FREE[FREE_counter].Free_Space=j-p;
}
}
}
voidFirst_Fit(PCB&a)//首次适应算法
{
inti,j,k;
for(i=0;iif(ROM[i]==0)
{
for(j=i;j<=(i+a.ProgressSize)&&jif(ROM[j]==1)
{
i=j+1;
break;
}
if(j==i+a.ProgressSize+1)
{
a.Startaddress=i;//设置作业的开始地址
a.ProgressState=1;//标记作业在内存中
for(k=i;k
ROM[k]=1;
printf("进程%s插入成功,进程%s的初始地址为%d,结束地址为%d\n",a.ProgressName,a.ProgressName,a.Startaddress,a.Startaddress+a.ProgressSize-1);
return;
}
}
if(i==N)//未查询到合适的区域
printf("插入失败,无可用空间!
\n");
}
voidNext_Fit(PCB&a)//循环首次适应算法来实现作业调度
{
inti,j,k;
for(i=p;i{
if(ROM[i]==0)
{
for(j=i;j<=(i+a.ProgressSize)&&jif(ROM[j]==1)
{
i=j+1;
break;
}
if(j==i+a.ProgressSize+1)//找到合适的空闲区
{
a.Startaddress=i;
a.ProgressState=1;
for(k=i;k
ROM[k]=1;
printf("插入成功,进程%s的初始地址为%d,结束地址为%d\n",a.ProgressName,a.Startaddress,a.Startaddress+a.ProgressSize-1);
p=i+a.ProgressSize;
return;
}
}
}
for(i=0;i
if(ROM[i]==0)
{
for(j=i;j<=(i+a.ProgressSize)&&j
if(ROM[j]==1)
{
i=j+1;
break;
}
if(j==i+a.ProgressSize+1)//成功找到结束,并标记当前P为现在的作业的尾部
{
a.Startaddress=i;
a.ProgressState=1;
for(k=i;k
ROM[k]=1;
printf("插入成功,进程%s的初始地址为%d\n",a.ProgressName,a.Startaddress);
p=i+a.ProgressSize;
break;
}
}
if(i==p)//查询两部分都未找到合适的区域,输出插入失败语句
printf("插入失败,无可用空间\n");
}
voidDelete(PCB&a)//删除作业,修改内存信息和初始化该作业信息
{
inti;
for(i=a.Startaddress;iROM[i]=0;
a.ProgressState=0;//状态标记为未使用
printf("进程%s删除成功\n",a.ProgressName);
}
intmain()
{
intchoose1,choose;
charProgressName[10];
PCBa;
init();
printf("\t主存空间的分配与回收\n");
printf("---------------------------------------\n");
printf("\t1、首次适应算法\n");
printf("\t2、循环首次适应算法\n");
printf("---------------------------------------\n");
printf("请选择分配算法:
");
scanf("%d",&choose1);
system("cls");
while
(1)
{
w:
system("cls");
printf("当前分配算法:
");
if(choose1==1)
printf("首次适应算法\n");
else
printf("循环首次适应算法\n");
printf("---------------------------------------\n");
printf("\t1、插入进程\n");
printf("\t2、删除进程\n");
printf("\t3、显示进程的信息\n");
printf("\t4、显示空闲区\n");
printf("---------------------------------------\n");
printf("请输入:
");
scanf("%d",&choose);
system("cls");
switch(choose)
{
case1:
printf("请输入进程名:
");
scanf("%s",&a.ProgressName);
printf("请输入进程的大小:
");
scanf("%d",&a.ProgressSize);
for(inti=0;iif(strcmp(num[i].ProgressName,a.ProgressName)==0)
{
printf("已存在同名进程,无法插入。
\n");
system("pause");
gotow;
}
if(choose1==1)//首次适应算法
First_Fit(a);
else
Next_Fit(a);//循环首次适应算法
num[count++]=a;
break;
case2:
if(count==0)
{
printf("当前没有进程在内存中,无法删除!
\n");
system("pause");
gotow;
}
printf("输入删除的进程名字:
");
scanf("%s",&ProgressName);
for(inti=0;iif(!
strcmp(num[i].ProgressName,ProgressName))
Delete(num[i]);
else
printf("没有找到对应进程,请重新输入。
\n");
break;
case3:
showProgress(a);
break;
case4:
find_FREE();
showFree();
break;
default:
printf("\n无效的输入。
\n");
}
system("pause");
}
return0;
}
主界面:
首次适应算法,初始空闲区:
插入进程:
插入3个进程:
空闲区信息:
删除进程2:
删除后空闲区状况:
再插入一个进程,可以看到其其初始地址为100:
循环首次适应算法,插入3个进程
删除进程2后:
再插入进程A,发现其从上次找到的空闲分区的下一个空闲分区开始查找,其初始地址为750而不是200: