List[j][i]=mem[j];
f[i]=flag;
}
3.4增加算法与比较
3.4.1增加FIFO算法
该算法总是淘汰最先进入内存的页面,即选择内存中驻留时间最久的页面予以淘汰。
该算法实现简单,在本次课程设计中,只需要将要访问的页面排成一个序列,然后判断当前访问页在物理块中是否存在,若在则标记为“*”,否则标记为“”,如果发生缺页,则先判断内存中是否有空旳物理块,有则得到空物理块的下标,将当前访问页插入到该物理块;没有则移除首物理块中的页面,即淘汰最先进入内存中的页面,其余物理块中的页面元素下标减一,当前访问页插入到末物理块。
如果标记为“”,则当前物理块中页面元素下标不变。
3.4.2分析比较
FIFO算法是先进先出,当当前内存中没有正要访问的页面时,置换出最先进来的页面。
LRU算法是最近最久未使用,当当前内存中没有正要访问的页面时,置换出在当前页面中最近最久没有使用的页面。
先进先出(FIFO)算法较易实现,比较适用于具有线性顺序特性的程序,而对其他特性的程序则效率不高。
缺页中断率为最佳算法的2~3倍;增加可用主存块的数量会导致更多的缺页,此算法还可能出现抖动现象异常。
最近最久未被使用(LRU)算法的实现需要硬件支持,基于程序的局部性原理,所以适用用大多数程序,此算实现必须维护一个特殊的队列——页面淘汰队列。
关键是确定页面最后访问以来所经历的时间。
四、程序测试
4.1运行结果及截图
按1进入自定义进程数和物理块数。
图4-1用户自定义输入
调用FIFO算法输出淘汰过程,计算页面访问命中率。
图4-2调用FIFO算法
调用LRU算法输出淘汰过程,计算页面访问命中率。
图4-3调用LRU算法
按4修改当前物理块的个数。
图4-4修改物理块数
修改物理块数后,调用FIFO算法输出。
图4-5修改物理块数调用FIFO算法
修改物理块数后,调用LRU算法输出。
图4-6修改物理块数调用LRU算法
选择随机生成页面访问序列的方式。
图4-7随机生成页面访问序列
随机生成页面访问序列后,调用FIFO算法输出。
图4-8调用FIFO算法
随机生成页面访问序列后,调用LRU算法输出。
图4-9调用LRU算法
修改物理块数后,调用LRU算法输出淘汰过程。
图4-10修改物理块数调用LRU算法
4.2思考题解答
4.2.1思考题
(1)
题目:
设计一个界地址存储管理的模拟系统,模拟界地址方式下存储区的分配和回收过程。
提示:
必须设置一个内存分配表,按照分配表中有关信息实施存储区的分配,并不断根据存储区的分配和回收修改该表。
算法有首次匹配法,循环首次匹配法和最佳匹配法等。
可用各种方法的比较来充实实习内容。
可使用碎片收集和复盖等技术。
答:
①分配时,根据用户提供的作业大小,从第一个空闲块开始查找,将找到的第一个足够大的空闲块块分配给该作业,返回给用户该块始地址。
如果该块剩余部分小于特定阈值(本程序为2k),将该块整体分配给此作业,将该块直接加入分配区链表,若剩余块大于或等于阈值,将分配块加入分配区链表,剩余部分作为新的空闲块.另:
程序开始时已将0到20k分配给操作系统。
②回收时,根据用户提供的作业的始地址,在分配区表查找,若找到该块,将其加入空闲区链表,提示用户释放成功。
若新形成的空闲块与其前后的空闲块相连,合并空闲块形成更大的空闲块。
③显示,用户可随时选择查看内存分配状态图以及空闲区表与分配区表,在分配或回收成功时,程序自动显示内存分配状态图、空闲区表与分配区表。
4.2.2思考题
(2)
题目:
自行设计或选用一种较为完善的内存管理方法,并加以实现。
提示:
设计一个段页式管理的模拟程序或通过一个实际系统的消化和分析,编制一个程序来模拟该系统。
答:
选择1分配内存,输入内存名和占用空间大小即可分配内存,显示的项目有进程名、起始地址和长度,已分配的内存分配情况会显示出来,;空间分配满则显示“无空闲区”;选择2回收内存,输入已分配的内存名称即可回收该内存;分配总空间大小为128,若输入的进程大于该数,则显示“占用空间过大,分配失败”。
具体如下所示:
图4-11按键选择1
图4-12内存分配情况
图4-13回收内存
图4-14分配内存失败
五、课程设计小结
在本次操作系统课程设计中,我们小组抽中的课设任务是请求页式存储管理中LRU算法的实现,由我担任小组长。
在熟悉了课设任务和课设要求后,我为各个组员分配了任务,思考题部分交给了组员,而我则负责课设主要程序代码的编写,画程序流程图,以及协助完成课设所需的所有资料。
在课堂上,我已经了解到,LRU算法是发生在缺页中断时,由于内存中没有空的物理块存放当前访问的页面,需要淘汰一个已在内存中的页面而采用的算法之一。
LRU算法即最近最久未使用算法,每次淘汰的页面是相对于现在最久没有被访问的页面。
参考关于LRU算法的题目,结合考试复习资料,我决定采用老师上课所讲的填表方式来输出LRU算法淘汰页面的过程。
在设计程序时,我另外增加了FIFO算法,用以比较页面淘汰过程。
为了提高代码的可重用性,我把程序设计成菜单选择的样式,总共五个菜单选项,分别是“1--用户自定义输入”、“2--先进先出算法FIFO”、“3--最近最少使用算法LRU”、“4--仅修改物理块数”、“0--退出程序”。
需要说明的是,程序运行一开始,首先得执行一次菜单选项1,用以初始化物理块数组中的页号,否则提示请选择菜单1,并返回主菜单重新输入菜单选项。
在设计输出页面淘汰过程时,我用一个页面序列数组,用于存放产生的页面访问序列;用缺页标记字符数组,用于输出当前访问页面是否缺页;一个二位字符数组,用于显示LRU算法或FIFO算法淘汰页面的过程;一个存放被淘汰页面的字符数组,用于输出被淘汰的页面。
在每种算法淘汰页面后,输出采用该算法计算出的缺页率和页面访问命中率。
在物理块数组中的页号初始化后,选择菜单4修改内存中物理块数,然后可以选择调用哪种算法输出页面淘汰过程,可以反复循环。
在测试淘汰页面过程的代码时,选择输入页面序列,调用算法输出结果,我对照事先填好的淘汰过程表,发现有的序列结果正确,有的不对,后来发现一个关键点,即空物理块的下标,修改了部分代码,终于使每种算法的淘汰过程输出正确。
通过本次课程设计,我重新复习了很多C语言的知识,对于想要实现的功能可以很好的用代码来完成,而且提高了自己的编程能力,加强了自己的团队合作能力,同时,我对LRU算法的了解也更加清晰明白了。
六、参考文献
[1]苏庆刚.操作系统原理与应用教程.上海:
上海交通大学出版社,2012.01.01
[2]胡志刚.谭长庚等.《计算机操作系统》.中南大学出版社.2005
[3]谭浩强.C程序设计(第四版).北京:
清华大学出版社.2010.06.04
[4]王旭阳,李睿.《操作系统原理》.北京:
机械工业出版社,2009
[5]汤子瀛等.《计算机操作系统》.西安电子科技大学出版社
1、请求页式存储管理中LRU算法的实现
#include
#include
#include
#definep30
#definew10
inti,j,q,m,n,sum;
charflag,f[p],lose[p],page[p],mem[w],List[w][p];
voidInit()//初始化函数
{
sum=0;//计算缺页次数的变量,初始值为0
for(inti=0;imem[i]='';//初始时,内存中物理块为空
for(i=0;ifor(j=0;jList[i][j]='';//初始时,用于显示页面淘汰过程的二维数组为空
}
voidFIFO()
{
for(i=0;i{
intlow=-1;//非空物理块标志
for(j=0;j{
if(mem[j]=='')
{
low=j;//得到第一个空物理块的下标
break;
}
}
lose[i]='';//初始化当前页面有效
q=0;
while((page[i]!
=mem[q])&&(q!
=m))//查询物理块中与当前访问页相同的页面下标
q++;
if(q==m)
flag='*';//缺页,则置标志flag为'*'
else
flag='';//不缺页
if(flag=='*')//物理块中没有当前访问页(如果有缺页)
{
if(low!
=-1)//存在一个物理块为空
mem[low]=page[i];//当前访问页直接插入到该物理块中
else//当前物理块装满页面
{
lose[i]=mem[0];//淘汰最先访问的页面
for(j=0;jmem[j]=mem[j+1];//淘汰第一个物理块中的页面,其余页面下标减一
mem[m-1]=page[i];//最后一个物理块保存当前访问页面
}
}
for(j=0;jList[j][i]=mem[j];//用当前物理块里的内容更新二维数组
f[i]=flag;//更新标记当前访问页是否缺页的字符数组
}
printf("\n\t------------------FIFO算法页面淘汰过程------------------\n\t");
for(i=0;i{
printf("%c",page[i]);
}
printf("\n\t--------------------------------------------------------\n\t");
for(i=0;i{
if(f[i]=='*')
sum++;//累加缺页次数
printf("%c",f[i]);
}
printf("\n\t--------------------------------------------------------\n\t");
for(i=0;i{
for(j=0;jprintf("%c",List[i][j]);//输出二维数组
printf("\n\t");
}
printf("--------------------------------------------------------\n\t");
for(i=0;iprintf("%c",lose[i]);
printf("\n\t--------------------------------------------------------\n");
printf("\n\t其中*代表缺页\n");
printf("\n\t被淘汰的页面依次为:
");
for(i=0;iif(lose[i]!
='')
printf("%c",lose[i]);
printf("\n\t缺页次数是:
%d缺页率是:
%f\n",sum,(double)sum/n);
printf("\n\tFIFO算法的页面访问命中率是:
%f\n",1-(double)sum/n);
}
voidLRU()
{
for(i=0;i{
intlow=-1;//物理块是否为空的标志
for(j=0;j{
if(mem[j]=='')//判断当前物理块是否有空的物理块
{
low=j;//得到第一个空物理块的下标
break;
}
}
lose[i]='';//初始化当前页面有效
q=0;
while((page[i]!
=mem[q])&&(q!
=m))
q++;
if(q==m)
flag='*';//缺页,则置标志flag为'*'
else
flag='';
if(flag=='*')
{
if(low!
=-1)//物理块中有空位
mem[low]=page[i];
else
{
lose[i]=mem[0];//淘汰最近最久未使用的页面
for(j=0;jmem[j]=mem[j+1];
mem[m-1]=page[i];
}
}
else
{
if(low!
=-1)
{
for(j=q;jmem[j]=mem[j+1];
mem[low-1]=page[i];
}
else
{
for(j=q;jmem[j]=mem[j+1];
mem[m-1]=page[i];
}
}
for(j=0;jList[j][i]=mem[j];
f[i]=flag;
}
printf("\n\t------------------LRU算法页面淘汰过程-------------------\n\t");
for(i=0;i{
printf("%c",page[i]);
}
printf("\n\t--------------------------------------------------------\n\t");
for(i=0;i{
if(f[i]=='*')
sum++;
printf("%c",f[i]);
}
printf("\n\t--------------------------------------------------------\n\t");
for(i=0;i{
for(j=0;jprintf("%c",List[i][j]);
printf("\n\t");
}
printf("--------------------------------------------------------\n\t");
for(i=0;iprintf("%c",lose[i]);
printf("\n\t--------------------------------------------------------\n");
printf("\n\t其中*代表缺页\n");
printf("\n\t被淘汰的页面依次为:
");
for(i=0;iif(lose[i]!
='')
printf("%c",lose[i]);
printf("\n\t缺页次数是:
%d缺页率是:
%f\n",sum,(double)sum/n);
printf("\n\tLRU算法的页面访问命中率是:
%f\n",1-(double)sum/n);
}
voidmemu()
{
printf("\n\n\t*****************页面置换算法的模拟实现*****************\n");
printf("\t┏━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
printf("\t┃1--用户自定义输入┃\n");
printf("\t┠─────────────────────────┨\n");
printf("\t┃2--先进先出算法FIFO┃\n");
printf("\t┠─────────────────────────┨\n");
printf("\t┃3--最近最少使用算法LRU┃