花椒操作系统实验报告3.docx
《花椒操作系统实验报告3.docx》由会员分享,可在线阅读,更多相关《花椒操作系统实验报告3.docx(17页珍藏版)》请在冰豆网上搜索。
花椒操作系统实验报告3
昆明理工大学信息工程与自动化学院学生实验报告
(2012—2013学年第二学期)
课程名称:
操作系统开课实验室:
信自楼4452013年5月16日
年级、专业、班
学号
姓名
成绩
实验项目名称
页面置换算法
指导教师
舒国锋
教师评语
教师签名:
年月日
一、实验要求
对给定的一个页面走向序列,请分别用先进先出算法和二次机会算法,计算淘汰页面的顺序、缺页次数和缺页率,具体的页面走向可参考教材例题或习题。
二、实验目的
存储管理的主要功能之一是合理地分配空间。
请求页式管理是一种常用的虚拟存储管理技术。
通过本次实验,要求学生通过编写和调试地址转换过程的模拟程序以加强对地址转换过程的了解,通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。
三、实验原理及基本技术路线图(方框原理图)
用C或C++语言模拟实现请求式分页管理。
要求实现:
页表的数据结构、分页式内存空间的分配及回收(建议采用位图法)、地址重定位、页面置换算法(从FIFO,LRU,NRU中任选一种)。
提示:
可先用动态申请的方式申请一大块空间,然后假设该空间为内存区域,对该空间进行页框的划分、分配等。
程序功能结构图:
流程图:
数据结构定义:
我提供定义了两个类。
第一个类就是页面类,在这类里面包括一些重要的数据成员。
有页号(page_no),页框号(frame_no),页面是否在内存的标志(flag(1表示在内存,0表示不在内存)),访问次数(times)。
另一个类是进程控制块类PCB。
类的数据成员有id(进程编号),name(进程名),size(进程大小),*p(页类指针)。
在本类中,有一些成员函数:
构造函数(用来初始化本类的所有数据),displayPCB(输出函数),convert(地址映射函数),allocation(分配函数),restore(回收函数)。
另外还有一些类外的函数:
initMemorySpace(初始化内存空间的函数),displayMemorySpace(输出内存空间的状态1(表示占用)0(表示空))。
四、所用仪器、材料(设备名称、型号、规格等)。
计算机一台
五、实验方法、步骤
程序代码:
#include
#include
#include
usingnamespacestd;
constintframe_size=1024;//页框长度,固定为1k
constintpage_size=1024;//页面长度,固定为1k
constintmemory_size=102400;//内存容量,固定为100k
constintframe_number=memory_size/frame_size;//100k/1k=100frames
int*memory;//指针变量,用来存内存的状态1还是0。
voidinitMemorySpace()//初始化内存空间
{
inti,ran,times;
time_tt;//定义time_t对象t
t=time(0);
srand(t);//随机改变每秒
times=0;//变量times初始化为0,变量的功能是检查内存空间是否有一半空了没。
memory=newint[frame_number];//申请内存空间,有frame_number这么大的空间
for(i=0;imemory[i]=1;//初始化全部为1
do
{
ran=rand()%frame_number;//随机空间位置
if(memory[ran]==0)continue;//如果当前的位置已经是空就要再循环
else//否则
{
memory[ran]=0;//内存空间在ran的位置为0(空)
times++;//times变量增加一个
}
}while(times<=(frame_number/2));//空的空间还没到内存空间的一半,再循环
}
voiddisplayMemorySpace()//输出内存空间状态,1还是0
{
inti;
cout<<"内存空间(0表示空,1表示占用)"<for(i=0;i{
cout<if((i+1)%10==0)cout<}
}
classpage//定义页表类page
{
public:
intlogic_no;//定义页号变量
intframe_no;//定义页框号变量
intflag;//定义内存标志变量,1表示在内存,0表示不在
inttimes;//定义访问次数变量
};
classPCB//定义进程控制块类PCB
{
private:
staticintid;//定义静态进程编号变量
stringname;//定义进程名为字符串类
intsize;//定义进程大小
intpage_number;//定义页面总数变量
intgiven_frame;//定义系统给的页框数变量
page*p;//类page的指针变量
public:
PCB();//本类的构造函数
voiddisplayPCB();//输出进程和页表的重要信息
voidconvert();//地址映射函数,也有淘汰方法(最近最少使用方法LRU)
intallocation(int);//分配函数。
函数里是按到页框号分配的
voidrestore();//回收函数。
用来回收内存空间
};
intPCB:
:
id=0;//初始化进程编号
voidPCB:
:
restore()//实现restore函数在类外
{
inti;
for(i=0;i{
memory[p[i].frame_no]=0;//请求到的页框号的内存空间改到被占用
}
}
intPCB:
:
allocation(intframe_no)//实现allocation函数体在类外部
{
if(memory[frame_no]==0)//如果内存空间是空的话
{
memory[frame_no]=1;//改该空间位置到1
return1;//返回1
}
return0;//如果对应的页框号在内存没有空间的话,返回0
}
PCB:
:
PCB()//实现构造函数体
{
inti,j,unused_page,*random_page,*page_no_array;
time_tt;
t=time(0);
srand(t);
id++;//自动增加进程编号一个
cout<<"请输入进程名:
";
cin>>name;//输入进程名
size=3072+rand()%48128;//初始化进程大小,随机从3页数到50页
page_number=(size/1024);//计算出页面数,进程大小除以一个页面的长度
given_frame=(page_number*2)/3;//固定页框数只是总页面数的三分之二
unused_page=page_number-given_frame;//空页面
p=newpage[page_number];//动态初始化类page的指针对象p
random_page=newint[given_frame];//动态初始化random_page指针变量
page_no_array=newint[page_number];//动态初始化page_no_array指针变量
for(i=0;i{
while
(1)
{
intrecord=0;
random_page[i]=rand()%page_number;//随机从0到page_number-1
for(j=0;j
{
if(random_page[i]==random_page[j])record++;//如果当前随机的值等于以前值
}
if(record==0)break;//如果当前随机的值不等于以前值
}
}
for(i=0;i{
intrecord=0;
for(j=0;j{
if(random_page[j]==i)record++;
}
if(record==0)page_no_array[i]=0;//如果第i个没有在random_page中,所以赋值为0
elsepage_no_array[i]=1;//否则第i个就赋值为1
}
for(i=0;i{
if(page_no_array[i]==1)//如果第i的page_no_array等于1,表示要放也页面
{
p[i].logic_no=i;//赋i的值给页号
do
{
while
(1)
{
intrecord=0;
p[i].frame_no=rand()%frame_number;//随机页框号,从0到frame_number-1
for(intj=0;j
{
if(p[i].frame_no==p[j].frame_no)record++;
}
if(record==0)break;//如果当前随机的值没有跟以前的值一样的话,结束loopwhile
(1)
}
}while((allocation(p[i].frame_no))==0);//如果要放到内存的位置不为空的话,再循环
p[i].flag=1;//页面在内存
p[i].times=1;//初始化访问次数为1
}
else//如果第i的page_no_array不等于1,表示是空页面
{
p[i].logic_no=i;//赋i的值给该页号
p[i].frame_no=-1;//赋-1给页框号,表示不在内存
p[i].flag=0;//赋0给flag,表示不在内存
p[i].times=0;//赋0给times,表示不在内存
}
}
}
voidPCB:
:
displayPCB()//实现displayPCB函数体
{
inti;
cout<<"进程ID:
"<"<"<cout<<"页号\t页框号\t内存标志访问次数"<for(i=0;i{
cout<<""<
}
}
voidPCB:
:
convert()//实现地址映射函数体
{
intlogicAddress,logicNumber,physicsAddress,innerAddress,physicsNumber,temppage,time,i;
//定义逻辑地址变量,逻辑页号,物理地址,页内地址,物理块号变量,和一些暂用变量
time=1000;//初始化time为1000表示最大访问次数
charch;
do
{
cout<<"Pleaseinputlogicaddress:
";
cin>>hex>>logicAddress;//输入逻辑地址为16进制
logicNumber=logicAddress>>10;//算出逻辑页号为高位
if(page_number-1else
{
cout<<"PageNo:
"<innerAddress=logicAddress&0x03ff;//页内地址为低10位
cout<<"InnerAddress:
"<if(p[logicNumber].flag==1)//如果算出的逻辑页号在内存,所以可以直接转换到物理地址,只要改对应页面的访问次数
{
p[logicNumber].times++;//对应的访问次数增加一个
}
else
{
for(i=0;i{
if(p[i].flag==1)//只要在内存才找比较
{
if(p[i].times