最近最少使用算法(LRU)——页面置换
原创
上一篇博客写了先进先出算法(FIFO)——页面置换:http://www.cnblogs.com/chiweiming/p/9058438.html
此篇介绍最近最少使用算法(LRU)——页面置换,与上一篇的代码大同小异,只是用了不同的方法从页面队列
中选出需要淘汰出的页面。(题目阐述看我上一篇博客)
还是辣个栗子:
现内存页面为: 15 31 24 17 18 5 9 26 4 21
部分地址流为: 4 31 24 17 18 26 17 5 5 9 31 18 18 21 15
页面 8 为下一个需要调入进去的页面,由于内存页面已满,需要使用LRU调出一个最近未被使用页面。
寻找淘汰页面的方式如下:
从页面 8 往前看,遇到与内存页面中相同的页面即把它移除(即不淘汰它),等到移除了 max_page-1 个页面之
后,剩下最后一个未被移除的页面即是需要淘汰出去的。
在上面例子中,依次将 15 21 18 31 9 5 17 26 24 (已经9个),剩下最后一个 4 即是需要淘汰出去的页面。
可以用这样的伪代码去实现:用一个数组 flag 来备份内存页块号中的页面,从 8 往前看,依次将之前的数和数组
里的数比较,若匹配成功,则将数组里面此位置 -1 ,等到置了 max_page-1 个 -1 后跳出;再从 flag 中筛选出不
是 -1 的值(即要淘汰出的页面),再拿此值和当前内存页面队列中的值比较,匹配成功则将此页面调出去,将页
面 8 调入。
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define max_page 10 //内存页面数 int Page[]={}; //虚拟存储区,存储320条指令,32个页面
int Page_flu[]={}; //存储320个页地址流
int count=; //计算随机产生的指令条数
double lack_page=; //记录缺页数
int count_page=max_page; //计算队列空页面个数
int flag[max_page+]={}; //存储内存块中的页面号
int ff=; struct Memo{ //用结构体存储内存页面块
int num; //给每个页面编号,方便将其从队列中找到并调出
int a;
struct Memo *next;
}; int Judge_Page(int value){ //输入指令,返回指令对面的页面号
return value/;
} int scan_queen(struct Memo *hear,int value){ //value代表页面号,扫描队列,缺页返回0,否则返回1
struct Memo *move;
move=hear->next;
while(move!=NULL){
if(move->a==value){
return ;
}
move=move->next;
}
return ;
} void print(struct Memo *hear){ //输出内存页面
struct Memo *move;
move=hear->next;
printf("当前页面队列为: ");
while(move!=NULL){
printf("%d ",move->a);
move=move->next;
}
printf("\n");
} void insert(struct Memo *hear,int value,int ZL,int x){ //将页面value调入内存,ZL为对应指令,x为页面value在页地址流中的序号
if(count_page>=){ //内存页面空间充足
struct Memo *move;
move=hear->next;
while(move->a!=-){
move=move->next;
}
move->a=value; //将页面调入
count_page--;
printf("页面 %d 被调入————对应指令为: %d \n",value,ZL);
}
else{ //内存空间不足,使用LRU选出需调出的页面后,将页面value后调入
struct Memo *move;
move=hear->next;
int i=;
for(i=;i<=max_page;i++){
flag[i]=move->a; //将内存块中的页面号放入flag备份
move=move->next;
}
int t=;
for(t=x-;t>=;t--){ //循环结束后flag里面只有一个不为0,把此页面调出即可
for(i=max_page;i>=;i--){
if(Page_flu[t]==flag[i]){
flag[i]=-;
ff++;
break;
}
}
if(ff==max_page-){
break;
}
}
for(i=;i<=max_page;i++){ //选出被淘汰出的页面号
if(flag[i]!=-){
ff=flag[i]; //备份要淘汰出的页面号
break;
}
}
move=hear->next;
while(move!=NULL){
if(move->a==ff){
int j=;
printf("前20个地址流为:");
for(j=x-;j<=x-;j++){
printf("%d ",Page_flu[j]);
}
printf("\n");
printf("页面 %d 被调出,页面 %d 被调入----指令为:%d \n",ff,value,ZL);
move->a=value; //将页面插入
break;
}
move=move->next;
}
} ff=;
print(hear); //调入后输出内存队列
} void LRU(struct Memo *hear){
int i=;
for(i=;i<=;i++){ //循环扫描页面
if( scan_queen(hear,Page_flu[i])==){ //判断是否缺页
lack_page++;
insert(hear,Page_flu[i],Page[i],i); //缺页将页面调入内存
}
else{ //不缺页
printf("指令 %d 对应页面 %d 已在内存\n",Page[i],Page_flu[i]);
}
//不缺页无需操作
}
} void Pro_Page(){ //形成页地址流函数
int m=; //在[0,319]的指令地址之间随机选取一起点m
m=rand()%; Page[count]=m;
count++;
if(count==){
return;
}
int m_=; //在前地址[0,m+1]中随机选取一条指令并执行
m_=rand()%(m+); Page[count]=m_;
count++;
if(count==){
return;
}
Page[count]=m_+;
count++;
if(count==){
return;
}
int m__=;
m__=(m_+)+rand()%( -(m_+)+ ); //在后地址[m_+2,319]的指令地址之间随机选取一条指令并执行
Page[count]=m__;
count++;
if(count==){
return;
} Pro_Page();
} void Flu(){ //将指令转换为页地址流
int i=;
for(i=;i<=;i++){
Page_flu[i]=Judge_Page( Page[i] );
}
} int main(){
struct Memo Stu[max_page+];
struct Memo *hear;
hear=&Stu[];
//*************************************
int i=;
for(i=;i<=max_page;i++){ //形成内存页面队列
if(i==max_page){
Stu[i].a=-;
Stu[i].next=NULL;
Stu[i].num=i;
break;
}
Stu[i].next=&Stu[i+];
Stu[i].a=-;
Stu[i].num=i;
}
//*************************************
srand(time()); //放在Pro_Page函数外面
Pro_Page(); //形成页地址流
Flu(); //形成页地址流
/*
printf("页地址流:\n");
for(i=0;i<=319;i++){ //输出页地址流
printf("%d ",Page[i]);
if(i%3==0 && i!=0){
printf("\n");
}
}
printf("\n");
*/
//************************************* LRU(hear);
printf("缺页次数为: %0.0lf\n",lack_page);
printf("命中率为:%lf\n",-lack_page/); return ;
}
(部分结果截图)
08:31:06
2018-05-22
最近最少使用算法(LRU)——页面置换的更多相关文章
- 操作系统-2-存储管理之LRU页面置换算法(LeetCode146)
LRU缓存机制 题目:运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制. 它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - ...
- 缓存算法(页面置换算法)-FIFO、LFU、LRU
在前一篇文章中通过leetcode的一道题目了解了LRU算法的具体设计思路,下面继续来探讨一下另外两种常见的Cache算法:FIFO.LFU 1.FIFO算法 FIFO(First in First ...
- LRU页面置换算法
本文以序列长度20的{ 7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};以及页面4:为例: #include <stdio.h> #define Init ...
- 页面置换算法 - FIFO、LFU、LRU
缓存算法(页面置换算法)-FIFO. LFU. LRU 在前一篇文章中通过leetcode的一道题目了解了LRU算法的具体设计思路,下面继续来探讨一下另外两种常见的Cache算法:FIFO. LFU ...
- 操作系统页面置换算法(opt,lru,fifo,clock)实现
选择调出页面的算法就称为页面置换算法.好的页面置换算法应有较低的页面更换频率,也就是说,应将以后不会再访问或者以后较长时间内不会再访问的页面先调出. 常见的置换算法有以下四种(以下来自操作系统课本). ...
- 页面置换算 - FIFO、LFU、LRU
缓存算法(页面置换算法)-FIFO.LFU.LRU 在前一篇文章中通过leetcode的一道题目了解了LRU算法的具体设计思路,下面继续来探讨一下另外两种常见的Cache算法:FIFO.LFU 1 ...
- 页面置换算法之Clock算法
1.前言 缓冲池是数据库最终的概念,数据库可以将一部分数据页放在内存中形成缓冲池,当需要一个数据页时,首先检查内存中的缓冲池是否有这个页面,如果有则直接命中返回,没有则从磁盘中读取这一页,然后缓存到内 ...
- [Operate System & Algorithm] 页面置换算法
页面置换算法是什么?我们看一下百度百科对页面置换算法给出的定义:在地址映射过程中,若在页面中发现所要访问的页面不在内存中,则产生缺页中断.当发生缺页中断时,如果操作系统内存中没有空闲页面,则操作系统必 ...
- OS_页面置换算法:C++实现
一.实验目的: 通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种页面置换算法的基本思想和实现过程,并比较它们的效率. 二.实验内容: 本实 ...
- Java--缓存热点数据,最近最少使用算法
1.最近最少使用算法LRU (Least recently used,最近最少使用) [实现]:最常见的是使用一个链表保存缓存数据 1.新数据插入到链表头部: 2.每当缓存命中(即缓存数据被访问),将 ...
随机推荐
- VC 6.0 MFC关闭对话框在win7出现崩溃的情况
Ctrl + W 掉出来class管理 添加OnDestory方法 void CPackUpItemToSetDlg::OnDestroy() { exit(1); CDialog::OnDestro ...
- kafka概要设计
Kafka核心功能 即:高性能的消息发送与高性能的消息消费 下载安装包后即可启动Kafka服务器,但是此前需要首先启动Zookeeper服务器,Zookeeper是为Kafka提供协调服务的工具,Ka ...
- java一些使用
随机数.输入.byte数组和string转换 一些可能会使用到的方法.供及时查找 ########################random类使用 Random random = new Rando ...
- Eclipse中的BuildPath详解【转载】
什么是Build Path? Build Path是指定Java工程所包含的资源属性集合. 在一个成熟的Java工程中,不仅仅有自己编写的源代码,还需要引用系统运行库(JRE).第三方的功能扩展库.工 ...
- canvas抛物线运动demo
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- python中执行shell命令
查看输出结果 import os output = os.popen('cat 6018_gap_5_predict/solusion2/solusion2_0-1.txt | wc -l') pri ...
- linq中当生成asp.net实体模式时
linq中当生成asp.net实体模式时 注意: 选中 工具->库程序包管理器->管理解决方案的nuget程序包 选中下面的进行下载.
- JSP基本指令
jsp命令指令用来设置与整个jsp页面相关的属性,它并不直接产生任何可见的输出,而只是告诉引擎如何处理其余JSP页面.其一般语法形式为: <%@ 指令名称 属性=“值”%> 三种命令指令分 ...
- Loadrunner手动关联详解
Loadrunner手动关联详解 一.关联的含义: 关联(correlation):在脚本回放过程中,客户端发出请求,通过关联函数所定义的左右边界值(也就是关联规则),在服务器所响应的内容中查找,得到 ...
- 循环获取某个class下的多个select的选中值
//循环获取某个class下的多个select的选中值 function eachSelect(cla){ var val = ""; $("."+cla).e ...