操作系统课程设计模拟设计页式存储管理的分配与回收Word格式.docx
《操作系统课程设计模拟设计页式存储管理的分配与回收Word格式.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计模拟设计页式存储管理的分配与回收Word格式.docx(23页珍藏版)》请在冰豆网上搜索。
⑷测试用例,运行结果和运行情况分析;
⑸自我评价和总结:
)你认为你完成的设计哪些地方做得比较好或比较出色;
)什么地方做得不太好,以后如何改正;
)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);
)完成本题是否有其他的其他方法(如果有,简要说明该方法);
)对实验题的评价和改进意见,请你推荐设计题目。
时间安排:
设计安排一周:
周1、周2:
完成程序分析及设计。
周2、周3:
完成程序调试及测试。
周4、周5:
验收,撰写课程设计报告。
(注意事项:
严禁抄袭,一旦发现,抄和被抄的一律按0分记)
指导教师签名:
年月日
系主任(或责任教师)签名:
模拟设计页式存储管理
的分配和回收
1需求分析
页式管理是一种内存空间存储管理的技术,页式管理分为静态页式管理和动态页式管理。
基本原理是将各进程的虚拟空间划分成若干个长度相等的页(page),页式管理把内存空间按页的大小划分成片或者页面(pageframe),然后把页式虚拟地址和内存地址建立一一对应页表,并用相应的硬件地址变换机构,来解决离散地址变换问题。
页式管理采用请求调页或预调页技术实现了内外存存储器的统一管理。
图1页的划分
图2基本页表示例
静态分页管理的第一步是为要求内存的作业或进程分配足够的页面。
系统通过
存储页面表、请求表以及页表来完成内存的分配工作。
页表指的是内存中的一块固定存储区。
页式管理时每个进程至少有一个页表。
请求表指的是用来确定作业或进程的虚拟空间的各页在内存中的实际对应位置;
另外整个系统有一个存储页面表,其描述了物理内存空间的分配使用状况。
图3请求表的示例
存储页面表有两种构成方法:
1、位示图法
2、空闲页面链表法
模拟设计页式存储管理的分配和回收要求能够满足如下的要求:
(1)输入给定的内存页面数,页面大小,进程的个数及每个进程的页数。
(2)要求当某进程提出申请空间的大小后,显示能否满足申请,以及为该进程分配资源后内存空间的使用情况(被进程占用的页面,空闲的页面)。
2功能设计
2.1算法分析
首先,请求表给出进程或作业要求的页面数。
然后,由存储页面表检查是否有足够的空闲页面,如果没有,则本次无法分配。
如果有则首先分配设置页表,并请求表中的相应表项后,按一定的查找算法搜索出所要求的空闲页面,并将对应的页好填入页表中。
图4分配页面的算法流程
2.2数据结构
页式管理把内存空间按页的大小划分成片或者页面,再按照一定的规律建立起页表,并通过请求表将分配内容显示出来.将页表和请求表的内容使用结构体来定义是比较方便的.
//页表项结构
typedefstruct_pagetableitem
{
pageidpagenum;
//页号
blockidblocknum;
//块号
}pgtabitem;
//页表
typedefpgtabitem*pagetable;
//请求表结构
typedefstruct_reqtable
{
unsignedpid;
//进程号
unsignedreqpagenum;
//请求页面数
pagetablepgtabadr;
//页表始址
boolstate;
//状态
}reqtabitem;
请求表还引入了支持快速插入和删除的list顺序容器来进行相关操作.
list<
reqtabitem>
reqtable
因为模拟设计的关系,页面的起始地址均应该为随机的数值,所以程序在
设计过程中加入了随机数类的编写.
classRandomNumber
private:
unsignedlongrandseed;
public:
RandomNumber(unsignedlongs=0);
unsignedshortRandom(unsignedlongn);
doublefRandom(void);
};
采用当前系统的时间值来生成伪随机数分配地址.
定义随机数产生器:
RandomNumberrandom
定义内存页面数:
intpagenum
定义页面大小:
intpagesize
定义进程个数:
intpnum
用整数数组模拟分配的内存页面数int*mempage=newint[pagenum]
2.3模块说明
2.3.1主函数
主函数依次运行了程序中所实现的关键函数.
intmain(){
InitSys();
//初始化系统
MainChoice();
//输出系统菜单
Destroy();
//释放申请的动态内存
return0;
}
2.3.2各个功能函数
初始化内存页面:
voidInit_Mempage(void)
获取内存使用情况:
intGet_Mempagenum(void)
初始化默认的请求表:
voidInit_Reqtable(void)
为默认的进程分配内存:
voidInit_DistMem(void)
手动创建进程,并分配内存:
voidDist_Mem(void)
释放申请的动态内存:
voidDestroy(void)
结束指定进程:
voidKill(void)
2.3.3打印函数
打印出进程请求表:
voidPrintReqtable(void)
打印出页表:
voidPrintPageTable(void)
打印出内存使用情况:
voidPrintMem(void)
打印出物理块的大小:
voidPrintBlockSize(void)
2.3.4其他函数
初始化系统:
voidInitSys(void)
输出主菜单:
voidMainMenu(void)
选择运行分支:
voidMainChoice()
3开发平台
3.1开发平台
(1)使用系统:
Windows7
(2)使用语言:
C++
(3)开发工具:
VisualC++2008
4测试用例,运行结果和运行情况分析
4.1测试方法
通过输入正常数据以及非正常数据对程序进行全方位测试
4.2测试结果
(1)程序主界面
(2)输入进程号和页面数:
(3)显示进程页表:
(4)显示请求表
(5)显示内存使用情况以及物理块大小
(6)错误检验
5源程序的主要部分
#include<
iostream>
cstdlib>
iomanip>
list>
#include"
page.h"
Random.h"
usingnamespacestd;
reqtable;
RandomNumberrandom;
//随机数产生器
unsignedpagenum=random.Random(80)+21;
//内存页面数21-100
unsignedpagesize=random.Random(16)+5;
//页面大小5-20
unsignedpnum=random.Random(4)+5;
//进程的个数5-8
int*mempage=newint[pagenum];
//用整数数组模拟内存页面数
/*初始化内存页面*/
voidInit_Mempage(void)
inti=0;
for(i=0;
i<
int(pagenum);
i++)
mempage[i]=0;
//数组全部赋初值
/*获取内存的使用情况*/
intGet_Mempagenum(void)
intsum=0;
for(inti=0;
if(mempage[i]==0)
sum++;
returnsum;
//判断有多少内存页面已经被使用
/*初始化默认的请求表*/
voidInit_Reqtable(void)
inti;
for(i=1;
=int(pnum);
{
reqtabitempreq;
preq.pid=i;
preq.reqpagenum=random.Random(4)+2;
//进程请求的页面大小-5
preq.state=false;
preq.pgtabadr=NULL;
reqtable.push_back(preq);
//依次压入容器
}
}
/*为默认的进程分配内存*/
voidInit_DistMem(void)
intreqpnum;
//进程请求页面数
list<
:
iteratorpos=reqtable.begin();
for(;
pos!
=reqtable.end();
pos++)
reqpnum=(*pos).reqpagenum;
if(reqpnum>
int(Get_Mempagenum()))//判断请求的内存页面数目是否大于剩余的
{
cout<
<
"
没有足够的内存!
endl;
cout<
}
else
(*pos).state=true;
pagetabletemp=newpgtabitem[reqpnum];
//新建临时页表项数组
if(temp==NULL)
{
cout<
内存分配失败!
exit(0);
}
(*pos).pgtabadr=temp;
for(i=0;
reqpnum;
temp[i].pagenum=i;
//页表的页号
intrandnum=random.Random(pagenum)+1;
//随机产生一个块号
while(mempage[randnum]==1)
randnum=random.Random(pagenum)+1;
temp[i].blocknum=randnum;
//页表的块号
mempage[randnum]=1;
/*手动创建进程,并分配内存*/
voidDist_Mem(void)
reqtabitempreq;
//新创建进程记录
intpid;
boolflag=false;
do{
请输入进程号:
;
flag=false;
cin>
>
pid;
for(list<
if((*pos).pid==pid)
flag=true;
该进程号已经存在,请重新输入"
break;
}while(flag==true);
//循环直到输入的Pid满足条件
preq.pid=pid;
cout<
请输入需要的页面数:
cin>
preq.reqpagenum=reqpnum;
preq.state=false;
preq.pgtabadr=NULL;
reqpnum=preq.reqpagenum;
if(reqpnum>
Get_Mempagenum())
没有足够的内存,进程创建失败!
else
preq.state=true;
pagetabletemp=newpgtabitem[reqpnum];
if(temp==NULL)
exit(0);
preq.pgtabadr=temp;
for(i=0;
int(reqpnum);
temp[i].pagenum=i;
intrandnum=random.Random(pagenum)+1;
while(mempage[randnum]==1)
randnum=random.Random(pagenum)+1;
temp[i].blocknum=randnum;
mempage[randnum]=1;
reqtable.push_back(preq);
//将该进程的记录加入请求表
/*程序结束时,释放申请的动态内存*/
voidDestroy(void)
for(pos=reqtable.begin();
if((*pos).state==true)
delete[](*pos).pgtabadr;
reqtable.clear();
/*打印出进程请求表*/
voidPrintReqtable(void)
|--------------------------------------------------------------------|"
|进程请求表|"
|"
setw(8)<
进程号"
<
setw(16)<
请求页面数"
<
页表起始地址"
页表长度"
状态|"
|---------------------------------------------------------------------|"
(*pos).pid
<
(*pos).reqpagenum
(*pos).pgtabadr
((*pos).reqpagenum)*pagesize;
if((*pos).state)
setw(4)<
已分配|"
else
未分配|"
if((*pos).pid!
=reqtable.back().pid)
/*打印页表*/
voidPrintPageTable(void)
if((*pos).pid==pid&
&
(*pos).state==true)
flag=true;
|---------------------------|"
|此进程的页表|"
页号"
setw(6)<
块号|"
intreqpagenum=(*pos).reqpagenum;
reqpagenum;
(*pos).pgtabadr[i].pagenum
<
(*pos).pgtabadr[i].blocknum<
|"
if(i!
=reqpagenum-1)
cout<
else
if(flag==false)
系统中不存在该进程或者该进程还没有被分配内存!
\n"
voidPrintMem(void)
内存总块数为"
pagenum<
已经使用了"
pagenum-Get_Mempagenum()<
块!
现在还有"
Get_Mempagenum()<
块内存区域空闲!
voidPrintBlockSize(void)
物理块大小为:
pagesize<
KB"
/*结束指定进程*/
voidKill(void)
boolflag;
reqtabitemtemp;
for(pos=reqtable.begin();
temp=*pos;
if(flag==false)
系统中不存在该进程!
}while(flag==false);
int(temp.reqpagenum);
mempage[temp.pgtabadr[i].blocknum]=0;
reqtable.remove(temp);
//重新为没有分配到内存的进程分配内存
if((*pos).state==false)
intreqpnum;
reqpnum=(*pos).reqpagenum;
if(reqpnum<
=Get_Mempagenum())
(*pos).state=true;
pagetabletemp=newpgtabitem[reqpnum];
if(temp==NULL)
{
exit(0);
}
(*pos).pgtabadr=temp;
for(i=0;
temp[i].pagenum=i;
intrandnum=random.Random(pagenum)+1;
while(mempage[randnum]==1)
randnum=random.Random(pagenum)+1;
temp[i].blocknum=randnum;
mempage[randnum]=1;
/*初始化系统*/
voidInitSys(v