操作系统实验三教学总结.docx
《操作系统实验三教学总结.docx》由会员分享,可在线阅读,更多相关《操作系统实验三教学总结.docx(21页珍藏版)》请在冰豆网上搜索。
操作系统实验三教学总结
操作系统实验—存储分配 收藏
[实验目的]
1.了解动态分区分配方式中使用的数据结构和分配算法,并进一步加深对动态分区存储管理方式及实现过程的理解。
2.通过对页面、页表、地址转换和页面转换过程的模拟,加深对请求调页系统的原理和实现过程的理解。
[实验内容和步骤]
-、动态分区分配方式的模拟
1. 用C语言分别实现采用首次适应算法和最佳适应算法的动态分区分配过程alloc()和回收过程free()。
其中,空闲分区通过空闲分区链管理;在进行内存分配时,系统优先使用空闲区低端的空间。
2. 假设初始状态下,可用的内在空间为640KB,并有下列的请求序列:
作业1申请130KB
作业2申请60KB
作业3申请100KB
作业2释放60KB
作业4申请200KB
作业3释放100KB
作业1释放130KB
作业5申请140KB
作业6申请60KB
作业7申请50KB
作业6释放60KB
请分别采用首次适应算法和最佳适应算法进行内存块的分配和回收,要求每次分配和回收后显示出空闲内存分区链的情况。
3. 源代码如下:
//******** 动态分区分配方式的模拟 *********
#include
#include
#defineFree0//空闲状态
#defineBusy1//已用状态
#defineOK1 //完成
#defineERROR0//出错
#defineMAX_length640//最大内存空间为640KB
typedefintStatus;
typedefstructfreearea//定义一个空闲区说明表结构
{ intID; //分区号
longsize; //分区大小
longaddress;//分区地址
intstate; //状态
}ElemType;
//---------- 线性表的双向链表存储结构 ------------
typedefstructDuLNode//doublelinkedlist
{ ElemTypedata;
structDuLNode*prior;//前趋指针
structDuLNode*next; //后继指针
}DuLNode,*DuLinkList;
DuLinkListblock_first;//头结点
DuLinkListblock_last; //尾结点
Statusalloc(int);//内存分配
Statusfree(int);//内存回收
StatusFirst_fit(int,int);//首次适应算法
StatusBest_fit(int,int);//最佳适应算法
voidshow();//查看分配
StatusInitblock();//开创空间表
StatusInitblock()//开创带头结点的内存空间链表
{
block_first=(DuLinkList)malloc(sizeof(DuLNode));
block_last=(DuLinkList)malloc(sizeof(DuLNode));
block_first->prior=NULL;
block_first->next=block_last;
block_last->prior=block_first;
block_last->next=NULL;
block_last->data.address=0;
block_last->data.size=MAX_length;
block_last->data.ID=0;
block_last->data.state=Free;
returnOK;
}
//----------------------- 分 配 主 存 -------------------------
Statusalloc(intch)
{
intID,request;
cout<<"请输入作业(分区号):
";
cin>>ID;
cout<<"请输入需要分配的主存大小(单位:
KB):
";
cin>>request;
if(request<0||request==0)
{
cout<<"分配大小不合适,请重试!
"< returnERROR;
}
if(ch==2)//选择最佳适应算法
{ if(Best_fit(ID,request)==OK)cout<<"分配成功!
"< elsecout<<"内存不足,分配失败!
"< returnOK;
}
else//默认首次适应算法
{ if(First_fit(ID,request)==OK)cout<<"分配成功!
"< elsecout<<"内存不足,分配失败!
"< returnOK;
}
}
//------------------ 首次适应算法 -----------------------
StatusFirst_fit(intID,intrequest)//传入作业名及申请量
{
//为申请作业开辟新空间且初始化
DuLinkListtemp=(DuLinkList)malloc(sizeof(DuLNode));
temp->data.ID=ID;
temp->data.size=request;
temp->data.state=Busy;
DuLNode*p=block_first->next;
while(p)
{
if(p->data.state==Free&&p->data.size==request)
{//有大小恰好合适的空闲块
p->data.state=Busy;
p->data.ID=ID;
returnOK;
break;
}
if(p->data.state==Free&&p->data.size>request)
{//有空闲块能满足需求且有剩余"
temp->prior=p->prior;
temp->next=p;
temp->data.address=p->data.address;
p->prior->next=temp;
p->prior=temp;
p->data.address=temp->data.address+temp->data.size;
p->data.size-=request;
returnOK;
break;
}
p=p->next;
}
returnERROR;
}
//-------------------- 最佳适应算法 ------------------------
StatusBest_fit(intID,intrequest)
{
intch;//记录最小剩余空间
DuLinkListtemp=(DuLinkList)malloc(sizeof(DuLNode));
temp->data.ID=ID;
temp->data.size=request;
temp->data.state=Busy;
DuLNode*p=block_first->next;
DuLNode*q=NULL;//记录最佳插入位置
while(p)//初始化最小空间和最佳位置
{
if(p->data.state==Free&&
(p->data.size>request||p->data.size==request))
{ q=p;
ch=p->data.size-request;
break;
}
p=p->next;
}
while(p)
{
if(p->data.state==Free&&p->data.size==request)
{//空闲块大小恰好合适
p->data.ID=ID;
p->data.state=Busy;
returnOK;
break;
}
if(p->data.state==Free&&p->data.size>request)
{//空闲块大于分配需求
if(p->data.size-request {
ch=p->data.size-request;//更新剩余最小值
q=p;//更新最佳位置指向
}
}
p=p->next;
}
if(q==NULL)returnERROR;//没有找到空闲块
else
{//找到了最佳位置并实现分配
temp->prior=q->prior;
temp->next=q;
temp->data.address=q->data.address;
q->prior->next=temp;
q->prior=temp;
q->data.address+=request;
q->data.size=ch;
returnOK;
}
}
//----------------------- 主 存 回 收 --------------------
Statusfree(intID)
{
DuLNode*p=block_first;
while(p)
{ if(p->data.ID==ID)
{
p->data.state=Free;
p->data.ID=Free;
if(p->prior->data.state==Free)//与前面的空闲块相连
{ p->prior->data.size+=p->data.size;
p->prior->next=p->next;
p->next->prior=p->prior;
}
if(p->next->data.state==Free)//与后面的空闲块相连
{
p->data.size+=p->next->data.size;
p->next->next->prior=p;
p->next=p->next->next;
}
break;
}
p=p->next;
}
returnOK;
}
//--------------- 显示主存分配情况 ------------------
voidshow()
{ cout<<"+++++++++++++++++++++++++++++++++++++++\n";
cout<<"+++ 主 存 分 配 情 况 +++\n";
cout<<"+++++++++++++++++++++++++++++++++++++++\n";
DuLNode*p=block_first->next;
while(p)
{ cout<<"分 区 号:
";
if(p->data.ID==Free)cout<<"Free"< elsecout<data.ID< cout<<"起始地址:
"<data.address< cout<<"分区大小:
"<data.size<<"KB"< cout<<"状 态:
";
if(p->data.state==Free)cout<<"空 闲"< elsecout<<"已分配"< cout<<"——————————————"< p=p->next;
}
}
//----------------------- 主 函 数---------------------------
voidmain()
{
intch;//算法选择标记
cout<<" 动态分区分配方式的模拟 \n";
cout<<"************************************\n";
cout<<"**1)首次适应算法 2)最佳适应算法 **\n";
cout<<"************************************\n";
cout<<"请选择分配算法:
";
cin>>ch;
Initblock();//开创空间表
intchoice; //操作选择标记
while
(1)
{
cout<<"********************************************\n";
cout<<"** 1:
分配内存 2:
回收内存 **\n";
cout<<"** 3:
查看分配 0:
退 出 **\n";
cout<<"********************************************\n";
cout<<"请输入您的操作 :
";
cin>>choice;
if(choice==1)alloc(ch);// 分配内存
elseif(choice==2) // 内存回收
{
intID;
cout<<"请输入您要释放的分区号:
";
cin>>ID;
free(ID);
}
elseif(choice==3)show();//显示主存
elseif(choice==0)break;//退出
else//输入操作有误
{ cout<<"输入有误,请重试!
"< continue;
}
}
}
二、请求调页存储管理方式的模拟
1.假设每个页面中可存放10条指令,分配给一个作业的内存块数为4
2.用C语言模拟一作业的执行过程。
该作业共有320条指令,即它的地址空间为32页,目前它的所有页都还未调入内存。
在模拟过程中,如果访问的指令已在内存,则显示其物理地址,并转下一条指令。
如果所访问的指令还未装入内存,则发生缺页,此时需记录缺页的次数,并将相应页调入内存。
如果4个内存块中均已装入该作业,则需进行页面转换。
最后显示其物理地址,并转下一条指令。
在所有320条指令执行完毕后,请计算并显示作业运行过程中发生的缺页率。
3.置换算法:
请分别考虑OPT、FIFO和LRU算法。
4.作业中指令的访问次序按下述原则生成:
50%的指令是顺序执行的
25%的指令是均匀分布在前地址部分
25%的指令是均匀分布在后地址部分
具体的实施办法:
①在[0,319]之间随机选取一条起始指令,其序号为m
②顺序执行下一条指令,即序号为m+1的指令
③通过随机数,跳转到前地址部分[0,m-1]中的某条指令处,其序号为m1;
④顺序执行下一条指令,即序号为m1+1的指令
⑤通过随机数,跳转到后地址部分[m1+2,319]中的某条指令处,其序号为m2;
⑥顺序执行下一条指令,即序号为m2+1的指令
⑦重复跳转到前地址部分、顺序执行、跳转到后地址部分、顺序执行的过程,直至执行320条指令。
5.关键知识 在进程运行过程中,若其所要访问的页面不在内存需把它们调入内存,但内存已 无空闲 空间时,为了保证该进程能正常运行,系统必须从内存中调出一页程序或数据,送磁盘的对换区中。
但应将哪个页面调出,所以需要根据一定的算法来确定。
在这一过程中,选择换出页面的算法称为页面置换算法。
一个好的页面置换算法,应具有较低的页面更换频率。
页面置换算法的好坏,将直接影响到系统的性能。
以下分别是实验要求的三个页面置换算法的介绍及设计思想。
⑴最佳置换算法(Optimal):
最佳置换算法是Blady在理论上提出的一种算法。
其所选择的被淘汰页是将来不再被使用,或者是在最远的将来才被访问的页面。
采用这种页面置换算法, 保证有最少的缺页率。
但由于目前还无法预知一个进程在内存的若干个页面中,哪个在最长的时间内不会被访问,因而,现实中该算法是无法实现的。
因此在该算法的模拟过程中,页面访问次序必须是给定的,具体实现为:
对每一个物理块设置一个整数型的访问标志位,当需要置换物理块中的某一页时,将每一个物理块中的页面号与当前需调入页以后的每一页面号进行比较,若物理块中的页面号与所有的页面号都不同,则该页即为将来不再使用的页,将访问标记设置为1000,表示将来不会用,设置为一个很大数;若找到页号相同的则将其访问次序记入访问标记,比较访问标记,最大的即为最久不会被访问的,将其换出。
⑵先进先出法(FirstInFirstOut):
该算法总是淘汰最先进入内存的页面,既选择在内存中驻留时间最久的页面予以淘汰。
在该算法的模拟过程中,每当某一页面进入内存时(包括页面置换时页面的置入),物理块中各页面访问标记自动加一,置换后,将置换页面所在的物理块中访问标记减一;这样能防止当物理块访问标记出现两个以上相同的值的错误执行,更好地模拟了先进先出法;
⑶最近最久未使用(LeastRecentlyUsed):
该算法以最近的过去作为不久将来的近似, 将过去最长一段时间里不曾被使用的页面置换掉。
在该算法的模拟过程中,每当物理块中的页面被访问时,便将其访问标记置为-1
以后每执行一条指令,便将物理块中各页面的访问标记加一,需置换时访问标记最大的便是将要被置换的。
四、 源代码
#include
#include
#include
#include
#defineBsize4
typedefstructBLOCK//声明一种新类型——物理块类型
{
intpagenum;