操作系统分区内存管理.docx
《操作系统分区内存管理.docx》由会员分享,可在线阅读,更多相关《操作系统分区内存管理.docx(12页珍藏版)》请在冰豆网上搜索。
![操作系统分区内存管理.docx](https://file1.bdocx.com/fileroot1/2023-2/3/fec53062-86cb-4548-91f9-cbd9b80f7beb/fec53062-86cb-4548-91f9-cbd9b80f7beb1.gif)
操作系统分区内存管理
洛阳理工学院实验报告
系别
计算机系
班级
学号
姓名
课程名称
计算机操作系统
实验日期
2015/10/26
实验名称
分区内存管理
成绩
实验目的:
过本次实验,加深对进程概念的理解,进一步掌握进程状态的转变及进程调度策略。
实验条件:
计算机一台,软件vc++6.0
一、实验目的
通过这次实验,加深对内存管理的认识,进一步掌握内存的分配、回收算法的思想。
二、实验原理
设计程序模拟内存的动态分区内存管理方法。
内存分区使用分区(说明)表进行管理,采用最先适应算法从分区表中寻找空闲区进行分配,内存回收时不考虑与相邻空闲区的合并。
假定系统的内存共640K,初始状态为操作系统本身占用40K。
t1时刻,为作业A、B、C分配80K、60K、100K、的内存空间;t2时刻作业B完成;t3时刻为作业D分配50K的内存空间;t4时刻作业C、A完成;t5时刻作业D完成。
要求编程序分别输出t1、t2、t3、t4、t5时刻内存的空闲分区。
三、实验内容
#include
#include
#include
#include
#definemaxPCB10
#definemaxPart10
#defineTRUE1
#defineFALSE0
typedefstructPCB_type
{
charname;//进程名
intaddress,len,valid;//进程所占分区起止、长度、该PCB有效标识(1有效,0无效)
}PCB;
typedefstructseqlist
{
PCBPCBelem[maxPCB];//maxPCB为系统中允许的最多进程数
inttotal;//系统中实际的进程数
}PCBseql;
typedefstructPartition
{
intaddress,len,valid;//分区起址、长度、有效标识(1空闲,0已分配)
}Part;
typedefstructPartlist
{
PartPartelem[maxPart];//maxPart为系统中可能的最多分区数
intsum;//系统中实际的分区数
}Partseql;
intlength=640;//系统有640的空闲
PCBseql*pcbl;
Partseql*partl;
voidinitpcb(PCBseql*vpcbl,intadr);//初始化进程表vpcbl
voidgetprint();
voidinitpart();//初始化分区表vpartl
voidrequest(charname,intlen);//进程name请求len大小的内存
voidrelease(charname);//回收name进程所占内存空间
voidprint();//输出内存空闲分区
/*
voidprintp()
{
inti;
for(i=0;i<(pcbl->total);i++)
{
printf("%c\n",pcbl->PCBelem[i].name);
}
}
*/
voidinitpcb(PCBseql*vpcbl,intadr)//初始化进程表vpcbl
{
inti=1;
PCB*pcbelem;
inttel;
charc;
pcbelem=vpcbl->PCBelem;
while(TRUE)
{
printf("请输入第%d进程名称",i++);
vpcbl->total++;
scanf("%c",&(pcbelem->name));
printf("请输入进程所需内存");
scanf("%d",&tel);
pcbelem->len=tel;
pcbelem->address=adr+tel;
pcbelem->valid=1;
pcbelem++;
printf("是否要继续输入进程(Enter-是Esc-否)\n");
fflush(stdin);
c=getch();
fflush(stdin);
if(c==27)
{
break;
}
}
}
voidinitpart()
{
charc,name;
intlen;
printf("请输入你的操作R.请求内存;P.输出空闲分区;S.强制进程结束;(N/n).退出\n");
fflush(stdin);
c=getchar();
fflush(stdin);
while(c!
='N'||c!
='n')
{
if(c=='R'||c=='r')
{
fflush(stdin);//做输入的时候要清空缓冲区
printf("请输入请求内存进程的名称,长度");
scanf("%c,%d",&name,&len);
request(name,len);//进程请求内存
}
elseif(c=='P'||c=='p')
{
printf("\t*****VIEWbegin*****\n");
getprint();
printf("\t*****VIEWend*****\n");
}
elseif(c=='S'||c=='s')
{
printf("请输入想要回收的进程名称\n");
scanf("%c",&name);
release(name);
}
printf("请输入你的操作R.请求内存;P.输出空闲分区;S.强制进程结束\n");
fflush(stdin);
c=getchar();
fflush(stdin);
}
}
voidinit4IOS(inttem)
{
Part*newPart=&partl->Partelem[0];
tem=tem>0?
(temtem:
length):
0;
newPart->address=0;
newPart->len=tem;
newPart->valid=1;
partl->sum++;
printf("------->已为操作系统分配了%dkb内存\n",tem);
newPart=&partl->Partelem[1];
newPart->address=tem;
length=tem=length-tem;
tem=tem<0?
(0):
tem;
newPart->len=tem;
newPart->valid=0;
partl->sum++;
printf("------->为操作系统分配后剩余的内存%dkb内存\n",tem);
}
intgetTagByPcb(charname)
{
inti=0;
for(;i<(pcbl->total);i++)
{
if(name==pcbl->PCBelem[i].name)
{
returni;
}
}
returnpcbl->total+1;
}
//分配出去就会产生一个碎片将元素后移动一位
voidArrayToRightOne(inti)
{
intleng=partl->sum;
while(leng>i)
{
partl->Partelem[leng].address=partl->Partelem[leng-1].address;
partl->Partelem[leng].len=partl->Partelem[leng-1].len;
partl->Partelem[leng].valid=partl->Partelem[leng-1].valid;
leng--;
}
partl->sum++;
}
intfindBylen(intlen)
{
inti=0;
while(isum)
{
if(partl->Partelem[i].valid==0)
{
if(len<=partl->Partelem[i].len)
{
returni;
}
}
i++;
}
return0;
}
voidrequest(charname,intlen)
{
chartem;
inti;//是name进程的下标
inttemBylen;
inttemByPcb;
temByPcb=getTagByPcb(name);
while(temByPcb>pcbl->total)
{
printf("找不到进程%c,重新输入Y/N",name);
fflush(stdin);
tem=getchar();
if(tem=='Y')
{
fflush(stdin);//做输入的时候要清空缓冲区
printf("请输入请求内存进程的名称,长度");
scanf("%c,%d",&name,&len);
if(len>pcbl->PCBelem[temByPcb].len)
{
printf("您请求的容量大于您进程最大要求量%d,",pcbl->PCBelem[temByPcb].len);
return;
}
}
if(tem=='N')
{
return;
}
}
//找到一块len内存
if(findBylen(len)==0)
{
//sort2part();//收集内存代码没写
}
if((i=findBylen(len))==0)
{
printf("警告内存已满无法分配\n");
}
//分配出去就会产生一个碎片将元素后移动一位10/16
ArrayToRightOne(i);
//直接对partl->Partelem[i]赋值并加入一个碎片
temBylen=partl->Partelem[i].len-len;
partl->Partelem[i].len=len;
partl->Partelem[i].valid=1;
//新的碎片
partl->Partelem[i+1].address=partl->Partelem[i].address+partl->Partelem[i].len;
partl->Partelem[i+1].len=temBylen;
partl->Partelem[i+1].valid=0;
//更新pcb的状态和容量
pcbl->PCBelem[temByPcb].address=partl->Partelem[i].address;
pcbl->PCBelem[temByPcb].len=pcbl->PCBelem[temByPcb].len-len;//更新pcb的len
pcbl->PCBelem[temByPcb].valid=1;
}
voidrelease(charname)
{
inti=0;
intadress,len;
if((getTagByPcb(name))<0)
{
printf("找不到进程名%c\n",name);
return;
}
elseif(pcbl->PCBelem[getTagByPcb(name)].valid=0)
{
printf("%c还没有运行请先运行\n",name);
}
printf("现在正回收%c的内存\n",name);
adress=pcbl->PCBelem[getTagByPcb(name)].address;
len=pcbl->PCBelem[getTagByPcb(name)].len;
while(isum)
{
if(adress==partl->Partelem[i].address)
{
partl->Partelem[i].valid=0;
}
i++;
}
}
voidgetprint()
{
inti;
printf("------空闲分区begin---------\n");
for(i=0;isum;i++)
{
if(partl->Partelem[i].valid==0)
{
printf("第%d块空闲内存起止为%d,容量为%d\n",i,partl->Partelem[i].address,partl->Partelem[i].len);
}
}
printf("------空闲分区end---------\n");
}
voidmain()
{
chartem;
intOSsize=40;
constintM=25;
pcbl=(PCBseql*)malloc(sizeof(PCBseql));
partl=(Partseql*)malloc(sizeof(Partseql));
partl->sum=0;
pcbl->total=0;
init4IOS(OSsize);
//为进程分配内存
initpcb(pcbl,OSsize);
initpart();
scanf("%c",&tem);
}
实验结果: