原创


上一篇博客写了先进先出算法(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)——页面置换的更多相关文章

  1. 操作系统-2-存储管理之LRU页面置换算法(LeetCode146)

    LRU缓存机制 题目:运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制. 它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - ...

  2. 缓存算法(页面置换算法)-FIFO、LFU、LRU

    在前一篇文章中通过leetcode的一道题目了解了LRU算法的具体设计思路,下面继续来探讨一下另外两种常见的Cache算法:FIFO.LFU 1.FIFO算法 FIFO(First in First ...

  3. 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 ...

  4. 页面置换算法 - FIFO、LFU、LRU

    缓存算法(页面置换算法)-FIFO. LFU. LRU 在前一篇文章中通过leetcode的一道题目了解了LRU算法的具体设计思路,下面继续来探讨一下另外两种常见的Cache算法:FIFO. LFU ...

  5. 操作系统页面置换算法(opt,lru,fifo,clock)实现

    选择调出页面的算法就称为页面置换算法.好的页面置换算法应有较低的页面更换频率,也就是说,应将以后不会再访问或者以后较长时间内不会再访问的页面先调出. 常见的置换算法有以下四种(以下来自操作系统课本). ...

  6. 页面置换算 - FIFO、LFU、LRU

      缓存算法(页面置换算法)-FIFO.LFU.LRU 在前一篇文章中通过leetcode的一道题目了解了LRU算法的具体设计思路,下面继续来探讨一下另外两种常见的Cache算法:FIFO.LFU 1 ...

  7. 页面置换算法之Clock算法

    1.前言 缓冲池是数据库最终的概念,数据库可以将一部分数据页放在内存中形成缓冲池,当需要一个数据页时,首先检查内存中的缓冲池是否有这个页面,如果有则直接命中返回,没有则从磁盘中读取这一页,然后缓存到内 ...

  8. [Operate System & Algorithm] 页面置换算法

    页面置换算法是什么?我们看一下百度百科对页面置换算法给出的定义:在地址映射过程中,若在页面中发现所要访问的页面不在内存中,则产生缺页中断.当发生缺页中断时,如果操作系统内存中没有空闲页面,则操作系统必 ...

  9. OS_页面置换算法:C++实现

    一.实验目的: 通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种页面置换算法的基本思想和实现过程,并比较它们的效率. 二.实验内容: 本实 ...

  10. Java--缓存热点数据,最近最少使用算法

    1.最近最少使用算法LRU (Least recently used,最近最少使用) [实现]:最常见的是使用一个链表保存缓存数据 1.新数据插入到链表头部: 2.每当缓存命中(即缓存数据被访问),将 ...

随机推荐

  1. RESTful的理解与设计【PHP】

    RESTful 就是一种软件架构的风格,以资源为中心定位,运用http的请求方式(动词)来划定操作.这样的设定优点简单易理解,方便人员对接,形成规范. 资源作为唯一标识,使用相关动词取获取操作.举例, ...

  2. Asp.Net MVC Identity 2.2.1 使用技巧(一)

    开发环境:vs2015 UP3  or  vs2017RC  项目环境:asp.net 4.6.1   identity版本为:asp.net identity 2.2.1 1.创建项目. 没什么好说 ...

  3. Mysql进阶-day2

    Mysql cmake方式安装 1.卸载原有mysql下载MySQL安装包 [root@localhost ~]# yum remove mysql* -y [root@localhost ~]# m ...

  4. jquery ui tabs(选项卡)插件

    参考文档:http://www.css88.com/jquery-ui-api/tabs/ html代码: <div id="tabs"> <ul> < ...

  5. unittest:1 用例编写

    unittest是python自带的单元测试框架,包含测试用例case,测试集suite,测试集加载loader,测试执行runner,测试结果result等. 简单使用:写一个用例类继承自unitt ...

  6. ipconfig命令一览

    前文用到了ipconfig /displaydns和ipconfig /flushdns,加上之前经常ipconfig查ip,今天看了一下别的命令,用的不多,仅作备忘~~ 命令行窗口中输入ipconf ...

  7. TTransport 概述

    TTransport TTransport主要作用是定义了IO读写操作以及本地缓存的操作,下面来看TIOStreamTransport是如何实现的. public abstract class TTr ...

  8. unbuntu 14安装 golang

    golang目前有两种编译,一种是golang官方提供的,另外一个是gnu提供的gccgo.这里安装的是Golang,从仓库安装(apt-get)        sudo apt-get instal ...

  9. BZOJ1334:[Baltic2008]Elect(背包DP)

    Description N个政党要组成一个联合内阁,每个党都有自己的席位数. 现在希望你找出一种方案,你选中的党的席位数要大于总数的一半,并且联合内阁的席位数越多越好. 对于一个联合内阁,如果某个政党 ...

  10. python——reuqests模块使用pip安装始终不成功

    使用pip install xxx 来安装某一库. 使用 pip uninstall xxx 来卸载. 而pip 的也可以采用常见的两种安装方法 在centos系列下 使用sudo yum insta ...