OS课程设计模拟内存分配算法MFC实现.docx
《OS课程设计模拟内存分配算法MFC实现.docx》由会员分享,可在线阅读,更多相关《OS课程设计模拟内存分配算法MFC实现.docx(19页珍藏版)》请在冰豆网上搜索。
![OS课程设计模拟内存分配算法MFC实现.docx](https://file1.bdocx.com/fileroot1/2023-1/8/b4723965-b965-47a3-b10a-875d1d64ba2d/b4723965-b965-47a3-b10a-875d1d64ba2d1.gif)
OS课程设计模拟内存分配算法MFC实现
课程设计报告
设计题目:
内存的连续分配算法
班级:
1003
学号:
211011023
姓名:
指导老师:
设计时间:
2012年8月
摘要
1、主要算法包括:
固定分区分配、动态分区分配、伙伴算法、可重定位分区分配。
2、内容要求:
1)定义与算法相关的数据结构,如PCB,空闲分区表;
2)至少实现两种以上分配算法,且用户可以选择在某次执行过程中使用何种算法;
3)在使用动态分区分配或可重定位分区分配算法时必须实现紧凑和对换功能;
4)动态分区分配和可重定位分区分配必选一个实现。
本系统模拟了操作系统内存分配算法的实现
,实现了固定分区分配和动态分区分配,以及可重定位分区分配算法,采用PCB定义结构体来表示一个进程,定义了进程的名称和大小,进程内存起始地址和进程状态。
内存分区表采用单链表来模拟实现。
关键词:
固定分区分配、动态分区分配、可重定位分区分配。
目录
1.概述……………………….4
2.课程设计任务及要求
2.1设计任务………………………..4
2.2设计要求………………………..4
3.算法及数据结构
3.1算法的总体思想(流程)………………………5
3.2PCB模块
3.2.1功能(运算)……………………….5
3.2.2数据结构(存储结构)……………………….5
3.2.3算法(实现)……………………….5
3.3进程队列模块
3.3.1功能………………………6
3.3.2数据结构………………………6
3.3.3算法………………………6
4.程序设计与实现
4.1程序流程图……………………..7
4.2程序说明(代码)
4.3实验结果……………………..9
5.结论……………………..10
6.参考文献。
……………………..10
7.收获、体会和建议。
……………………..10
一:
概述
本系统模拟了操作系统内存分配算法的实现,实现了固定分区分配和动态分区分配,以及可重定位分区分配算法,采用PCB定义结构体来表示一个进程,定义了进程的名称和大小,进程内存起始地址和进程状态。
内存分区表采用单链表来模拟实现。
固定分区实现就是将单链表的每个节点的大小设为固定大小,系统默认如果按固定分区分配的话,只能分成20个相等大小的分区,因此系统只能最多运行20个进程。
动态分区的实现是根据进程所申请的内存大小来决定动态的有系统进行分配内存空间大小,因此分区表里的空闲分区个数是不定的,根据进程数和进程大小决定的。
可重定位分区算法比动态分区算法增加了紧凑和进程对换的功能。
二:
课程设计任务及要求
设计任务:
使用C++MFC实现模拟操作系统内存分配算法的实现,定义结构体数据结构表示进程,定义单链表表示内存分区表。
设计要求:
定义与算法相关的数据结构,如PCB,空闲分区表;
至少实现两种以上分配算法,且用户可以选择在某次执行过程中使用何种算法;
在使用动态分区分配或可重定位分区分配算法时必须实现紧凑和对换功能;
动态分区分配和可重定位分区分配必选一个实现。
三:
算法及数据结构
#definefree0//表示进程状态空闲
#definebusy1//表示进程状态忙
typedefintStatus;//表示进程状态
structPCB//表示进程PCB结构体
{
CStringname;//进程name
Statusstatus;//进程状态busyorfree
intlStartAddres;//进程起始地址
intSize;//进程大小
};
structNode//表示组成链表的结点结构体
{
PCBdata;
Node*next;
};
classQueue//表示分区表的单链表类
{
public:
Queue();
~Queue(){}
//voidShow();//内存区分配情况显示
intGetLength();
intGetAllFree();//获得所有空闲分区总大小
voidInitialMemory(int);//初始化内存区域大小
voidFixedPartitonAlloc();//固定分区分配初始化空闲内存链表
boolAllocProFixed(CString,int);//为进程分配内存(执行固定分区分配算法)
boolAllocProDynamic(CString,int);//为进程分配内存(动态分区分配)
boolFreeMemory(CString);//释放进程内存
boolAllMerge(int);//内存紧凑分区算法
boolSwaping(int,PCB&);//进程对换算法
Node*GetFirst();//返回头结点
voidClear();//链表节点清除
private:
Node*first;
};
#include"StdAfx.h"
#include"Queue.h"
Queue:
:
Queue()
{
//默认头结点数据
first=newNode;
first->data.lStartAddres=0;
first->data.name="";
first->data.Size=0;
first->data.status=busy;
first->next=NULL;
}
intQueue:
:
GetLength()
{
intn=0;
Node*p=first;
while(p->next)
{
p=p->next;
n++;
}
returnn;
}
Node*Queue:
:
GetFirst()
{
returnfirst;
}
intQueue:
:
GetAllFree()
{
intn=0;
Node*p=first;
while(p->next)
{
p=p->next;
if(p->data.status==free)
{
n+=p->data.Size;
}
}
returnn;
}
//voidQueue:
:
Show()
//{
//Node*p=first;
//while(p->next)
//{
//p=p->next;
//cout<<"分区号:
"<data.name<//cout<<"分区状态:
"<<(p->data.status==busy?
"busy":
"free")<//cout<<"分区起始地址:
"<data.lStartAddres<//cout<<"分区大小:
"<data.Size<//cout<<"--------------------------------\n";
//}
//}
voidQueue:
:
InitialMemory(inti)
{
PCBtmp;
tmp.name="";
tmp.status=free;
tmp.lStartAddres=0;
tmp.Size=i;
Node*s=newNode;
s->data=tmp;
first->next=s;
s->next=NULL;
}
voidQueue:
:
Clear()
{
Node*q;
Node*p=first->next;
while(p->next)
{
q=p;
p=p->next;
deleteq;
}
}
voidQueue:
:
FixedPartitonAlloc()
{
PCBtmp;
intAllSize=first->next->data.Size;
intperSize=AllSize/20;
first->next->data.Size=perSize;
Node*p=first;
for(inti=1;i<20;i++)
{
while(p->next)
{
p=p->next;
}
tmp.name="";
tmp.status=free;
tmp.lStartAddres=i*perSize+1;
tmp.Size=perSize;
Node*s=newNode;
s->data=tmp;
p->next=s;
s->next=NULL;
}
}
boolQueue:
:
AllocProFixed(CString_name,int_size)
{
PCBtmp;
Node*p=first;
while(p->next)
{
p=p->next;
if(p->data.Size>=_size&&p->data.status==free)
{
p->data.name=_name;
p->data.status=busy;
returntrue;
}
}
returnfalse;
}
voidQueue:
:
SortList()
{
Node*p=NULL;
Node*q=NULL;
for(p=first->next;p->next;p=p->next)
for(q=p->next;q;q=q->next)
{
if(p->data.Size>q->data.Size)
{
PCBtmp;
tmp=p->data;
p->data=q->data;
q->data=tmp;
}
}
}
//动态分区分配算法(最佳适应算法)
boolQueue:
:
AllocProDynamic(CString_name,int_size)
{
Node*p=first;
Node*q=NULL;//用来记录最佳插入点位置
intch=0;//用来记录最小碎片值
while(p->next)
{
p=p->next;
//分区大小正好和进程大小相等
if(p->data.status==free&&p->data.Size==_size)
{
p->data.name=_name;
p->data.status=busy;
returntrue;
}
if(p->data.status==free&&p->data.Size>_size)
{
ch=p->data.Size-_size;
q=p;
break;
}
/*
//分区大小大于进程大小,分割分区,并按大小分区排序
if(p->data.Size>_size&&p->data.status==free)
{
Node*s=newNode;
inttmp=p->data.Size-_size;
if(tmp>_size)
{
s->data.lStartAddres=p->data.lStartAddres;
s->data.Size=_size;
s->data.name=_name;
s->data.status=busy;
p->data.lStartAddres+=_size;
p->data.Size=tmp;
s->next=q->next;
q->next=s;
SortList();//对分区链表进行按大小有小到大排序
returntrue;
}
else
{
s->data.lStartAddres=p->data.lStartAddres+tmp;
s->data.name=_name;
s->data.Size=_size;
s->data.status=busy;
p->data.Size=tmp;
s->next=p->next;
p->next=s;
SortList();//对分区链表进行按大小有小到大排序
returntrue;
}
*/
}
while(p)
{
if(p->data.status==free&&p->data.Size>=_size)
{
if(p->data.Size-_size{
ch=p->data.Size-_size;
q=p;
}
}
p=p->next;
}
if(q==NULL)
{
returnfalse;
}
else
{
Node*s=newNode;
s->data.lStartAddres=q->data.lStartAddres+ch;
s->data.name=_name;
s->data.Size=_size;
s->data.status=busy;
q->data.Size=ch;
s->next=q->next;
q->next=s;
returntrue;
}
}
boolQueue:
:
FreeMemory(CString_name)
{
Node*p=first;
Node*q;
while(p->next)
{
q=p;
p=p->next;
if(p->data.name==_name)
{
p->data.name="";
p->data.status=free;
//进行相邻分区合并
if(q->data.status==free)
{
q->data.Size+=p->data.Size;
q->next=p->next;
}
//判断是否为链表尾
if(p->next!
=NULL)
{
if(p->next->data.status==free)
{
p->data.Size+=p->next->data.Size;
p->next=p->next->next;
}
}
returntrue;
}
}
returnfalse;
}
boolQueue:
:
AllMerge(int_size)
{
Node*p=first;
Node*q;
intsum=0;
boolflag=true;//标志是否为第一次找到free分区
while(p->next)
{
while(p->next)
{
q=p;
p=p->next;
if(p->data.status==free&&flag)
{
sum=p->data.Size;
q->next=p->next;
flag=false;
break;
}
if(!
flag&&p->data.status==busy)
{
//对数据进行重定位
p->data.lStartAddres-=sum;
}
if(p->data.status==free&&!
flag)
{
p->data.Size+=sum;
//对数据进行重定位
p->data.lStartAddres-=sum;
if(p->data.Size>=_size)
{
returntrue;
}
q->next=p->next;
sum=p->data.Size;
break;
}
}
while(p)
{
q=p;
p=p->next;
if(p->data.status==free)
{
p->data.Size+=sum;
//对数据进行重定位
p->data.lStartAddres-=sum;
if(p->data.Size>_size)
{
returntrue;
}
q->next=p->next;
sum=p->data.Size;
break;
}
else
{
//对数据进行重定位
p->data.lStartAddres-=sum;
}
}
}
returnfalse;
}
boolQueue:
:
Swaping(intneedSize,PCB&pro)
{
Node*p=first;
//Node*q;
while(p->next)
{
p=p->next;
if(p->data.Size>=needSize)
{
pro=p->data;
p->data.name="";
p->data.status=free;
returntrue;
}
}
returnfalse;
}
四:
程序设计与实现。
流程图
固定分区分配流程图:
默认1000KB内存大小
总共分为20个相等大小分区
动态分区分配算法:
可重定位分区分配算法:
实验结果:
五:
收获,体会和建议
此次课程设计让我进一步加深了对操作系统内存分配算法的的理解,此次试验自己花了不少时间研究课本和课外资料,在写可重定位分区分配算法遇到了内存紧凑算法方面的难题,如何对内存剩余空间大小进行紧凑利用,花了好些时间不断的实验,不断的调试代码,最后终于写好了,并加以测试代码的健壮性,完成并测试了本次操作系统课程设计。
期间虽然遇到了很多困难,但自己最后因为这些困难而收获到了不少知识,加强了自己动手写代码的能力,对代码调式技术进一步掌握,对操作系统也产生了更浓厚的兴趣,自己一定还要多花时间研究操作系统,争取进一步理解操作系统并能够将优秀算法加以运用到自己以后的代码中。
六:
参考资料和书籍。
《VisualC++深入讲解》孙鑫
《计算机操作系统》汤子瀛
《C++程序设计》谭浩强
PS:
如果程序不能正确编译成功,请换用VS2008编译,并尝试删除Debug目录下的
.pch文件