LRU(Least Recently Used)最近未使用置换算法--c实现
在OS中,一些程序的大小超过内存的大小(比如好几十G的游戏要在16G的内存上跑),便产生了虚拟内存的概念
我们通过给每个进程适当的物理块(内存),只让经常被调用的页面常驻在物理块上,不常用的页面就放在外存,等到要用的时候再从外存调入,从而实现虚拟内存
但是因为给的每个进程的物理块大小不可能是无限的,如果该进程的物理块用完了这时候又要调入新的页面进来的话,就需要用到置换算法,其中的一个算法就叫
————>LRU(Least Recently Used)最近未使用置换算法
一、代码思想
这个算法的思想就是把已经很久没用过的页面,调出物理块然后加入新的准备调入进来的页面,对于每个物理块有两个元素
【页面号丨此页面至上次被访问以来的时间t】
我用了二维数组buffer[][2]来实现,buffer[i][0]表示的是在第i个物理块里的页面号,buffer[i][1]示的是在第i个物理块里的页面号已经有多久没用被调用过了
二,全部代码

1 #include <iostream>
2 using namespace std;
3
4 int max(int arr[][2], int n)
5 {
6 int ans = 0;
7 for (int i = 0; i < n; i++)
8 {
9 if (arr[i][1] > arr[ans][1])
10 {
11 ans = i;
12 }
13 }
14 return ans;
15 }
16
17 void check(int buffer[][2],int n)
18 {
19 for (int i = 0; i < 3; i++)
20 {
21 cout << buffer[i][0] << ' ';
22 }
23 cout << endl << "--------" << endl;
24 }
25
26 int exist_page_in_buffer(int buffer[][2], int page, int buffer_size)
27 {
28 for (int i = 0; i < buffer_size; i++)
29 {
30 if (buffer[i][0] == page)
31 {
32 return i;
33 }
34 }
35 return -1;
36 }
37
38 void one_turn(int buffer[][2], int i)
39 {
40 for (int k = 0; k < i; k++)
41 {
42 buffer[k][1]++;
43 }
44 }
45
46 void least_recently_used(int buffer[][2], int page[], int buffer_size, int page_size)
47 {
48 for (int i = 0; i < buffer_size; i++)//初始化buffer
49 {
50 buffer[i][0] = -1;
51 buffer[i][1] = 0;
52 }
53 for(int i = 0, j = 0; j < page_size;)//当页面全部调用完成时(j >= page_size),算法结束
54 {
55 //i是当前物理块中已经有多少页面了,j是已经有多少页面进行过置换了
56 if (exist_page_in_buffer(buffer, page[j], i) != -1 )//当前的页面page[j]已经存在于物理块buffer之中
57 {
58 one_turn(buffer, i); //过了一个调用周期
59 buffer[exist_page_in_buffer(buffer, page[j], i)][1] = 0;//这个page又被调用一次,所以t为0
60 check(buffer, i);
61 j++;
62 }
63 else//当前的页面page[j]不存在于物理块buffer之中
64 {
65 if (i < buffer_size)//如果物理块还没有满的话,直接加一个页面进来,就不进行置换了
66 {
67 buffer[i][0] = page[j];
68 one_turn(buffer, i);
69 check(buffer, i);
70 i++; //当前物理块中的页面个数加一,因为buffer没满,加到满为止
71 j++;
72 }
73 else//物理块已经满了,进行LRU的查找置换
74 {
75 int temp = max(buffer, buffer_size);//找一个最久没有被调用的页面进行置换
76 buffer[temp][0] = page[j];
77 one_turn(buffer, buffer_size);
78 buffer[temp][1] = 0;//这个page被置换进来调用一次,所以t为0
79 check(buffer, i);
80 j++;
81 }
82 }
83 }
84 }
85
86 int main()
87 {
88 int page[] = { 7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1 };
89 int buffer[3][2];
90 int n = sizeof(page)/sizeof(int);
91 least_recently_used(buffer, page, 3, 20);
92 }
三、代码解释
首先主函数调用LRU算法,函数least_recently_used进入函数栈,page的数据来源我会在下面给出例题

1 int main()
2 {
3 int page[] = { 7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1 };
4 int buffer[3][2];
5 int n = sizeof(page)/sizeof(int);
6 least_recently_used(buffer, page, 3, 20);
7 }
然后调用函数least_recently_used,首先进行对于buffer的初始化,然后进行循环调用页面,当页面全部调用完成时(j >= page_size),算法结束

1 void least_recently_used(int buffer[][2], int page[], int buffer_size, int page_size)
2 {
3 for (int i = 0; i < buffer_size; i++)//初始化buffer
4 {
5 buffer[i][0] = -1;
6 buffer[i][1] = 0;
7 }
8 for(int i = 0, j = 0; j < page_size;)//当页面全部调用完成时(j >= page_size),算法结束
9 {
10 //i是当前物理块中已经有多少页面了,j是已经有多少页面进行过置换了
11 if (exist_page_in_buffer(buffer, page[j], i) != -1 )//当前的页面page[j]已经存在于物理块buffer之中
12 {
13 one_turn(buffer, i); //过了一个调用周期
14 buffer[exist_page_in_buffer(buffer, page[j], i)][1] = 0;//这个page又被调用一次,所以t为0
15 check(buffer, i);
16 j++;
17 }
18 else//当前的页面page[j]不存在于物理块buffer之中
19 {
20 if (i < buffer_size)//如果物理块还没有满的话,直接加一个页面进来,就不进行置换了
21 {
22 buffer[i][0] = page[j];
23 one_turn(buffer, i);
24 check(buffer, i);
25 i++; //当前物理块中的页面个数加一,因为buffer没满,加到满为止
26 j++;
27 }
28 else//物理块已经满了,进行LRU的查找置换
29 {
30 int temp = max(buffer, buffer_size);//找一个最久没有被调用的页面进行置换
31 buffer[temp][0] = page[j];
32 one_turn(buffer, buffer_size);
33 buffer[temp][1] = 0;//这个page被置换进来调用一次,所以t为0
34 check(buffer, i);
35 j++;
36 }
37 }
38 }
39 }
再解释一下每个函数的作用
max,这个就是从buffer里找到最久没用调用过的页面,返回他的所在物理块的位置

1 int max(int arr[][2], int n)
2 {
3 int ans = 0;
4 for (int i = 0; i < n; i++)
5 {
6 if (arr[i][1] > arr[ans][1])
7 {
8 ans = i;
9 }
10 }
11 return ans;
12 }
check,检查函数的运行情况

1 void check(int buffer[][2],int n)
2 {
3 for (int i = 0; i < 3; i++)
4 {
5 cout << buffer[i][0] << ' ';
6 }
7 cout << endl << "--------" << endl;
8 }
exist_page_in_buffer,每次调入页面时,都先检查一遍这个页面有没有已经被调入到当前的物理块中,如果在,返回此页面在物理块中的位置,如果不在,返回-1

1 int exist_page_in_buffer(int buffer[][2], int page, int buffer_size)
2 {
3 for (int i = 0; i < buffer_size; i++)
4 {
5 if (buffer[i][0] == page)
6 {
7 return i;
8 }
9 }
10 return -1;
11 }
one_turn,过了一个调用周期(主要就是为了让其他的page距离上次被调用的时间t++)

1 void one_turn(int buffer[][2], int i)
2 {
3 for (int k = 0; k < i; k++)
4 {
5 buffer[k][1]++;
6 }
7 }
四、书上例题和运行结果

运算结果如下
7 -1 -1
--------
7 0 -1
--------
7 0 1
--------
2 0 1
--------
2 0 1
--------
2 0 3
--------
2 0 3
--------
4 0 3
--------
4 0 2
--------
4 3 2
--------
0 3 2
--------
0 3 2
--------
0 3 2
--------
1 3 2
--------
1 3 2
--------
1 0 2
--------
1 0 2
--------
1 0 7
--------
1 0 7
--------
1 0 7
--------
LRU(Least Recently Used)最近未使用置换算法--c实现的更多相关文章
- 深入理解【缺页中断】及FIFO、LRU、OPT这三种置换算法
缺页中断(英语:Page fault,又名硬错误.硬中断.分页错误.寻页缺失.缺页中断.页故障等)指的是当软件试图访问已映射在虚拟地址空间中,但是目前并未被加载在物理内存中的一个分页时,由中央处理器的 ...
- 页面置换算法——最近最久未使用算法(c语言实现)
操作系统实验:用C语言编程实现最近最久未使用置换算法(LRU) 最近最久未使用置换算法(LRU),全称Least Recently Used,是一种页面置换算法. 对于在内存中但又不用的数据块(内存块 ...
- 页面置换算法(最佳置换算法、FIFO置换算法、LRU置换算法、LFU置换算法)
页面置换产生的原因是:分页请求式存储管理(它是实现虚拟存储管理的方法之一,其中一个特性是多次性-->多次将页面换入或换出内存) 效果最好的页面置换算法:最佳置换算法 比较常用的页面置换算法有:F ...
- 操作系统笔记(六)页面置换算法 FIFO法 LRU最近最久未使用法 CLOCK法 二次机会法
前篇在此: 操作系统笔记(五) 虚拟内存,覆盖和交换技术 操作系统 笔记(三)计算机体系结构,地址空间.连续内存分配(四)非连续内存分配:分段,分页 内容不多,就不做index了. 功能:当缺页中断发 ...
- 页面置换算法-LRU(Least Recently Used)c++实现
最近最久未使用(LRU)置换算法 #include <iostream> #include <cstdio> #include <cstring> #include ...
- 操作系统页面置换算法(opt,lru,fifo,clock)实现
选择调出页面的算法就称为页面置换算法.好的页面置换算法应有较低的页面更换频率,也就是说,应将以后不会再访问或者以后较长时间内不会再访问的页面先调出. 常见的置换算法有以下四种(以下来自操作系统课本). ...
- (待续)C#语言中的动态数组(ArrayList)模拟常用页面置换算法(FIFO、LRU、Optimal)
目录 00 简介 01 算法概述 02 公用方法与变量解释 03 先进先出置换算法(FIFO) 04 最近最久未使用(LRU)算法 05 最佳置换算法(OPT) 00 简介 页面置换算法主要是记录内存 ...
- 操作系统 页面置换算法LRU和FIFO
LRU(Least Recently Used)最少使用页面置换算法,顾名思义,就是替换掉最少使用的页面. FIFO(first in first out,先进先出)页面置换算法,这是的最早出现的置换 ...
- FIFO、LRU、OPT这三种置换算法的缺页次数
考虑下述页面走向: 1,2,3,4,2,1,5,6,2,1,2,3,7,6,3,2,1,2,3,6 当内存块数量分别为3时,试问FIFO.LRU.OPT这三种置换算法的缺页次数各是多少? 答:缺页定义 ...
随机推荐
- 开源抓包工具PowerSniff(支持lua,c语言作为脚本实时分析)
做这个程序的意图是wireshark插件编写复杂(虽然也支持lua),而轻量级的工具如smartsniff,minisniff不支持插件化数据分析,各种工具用下来或多或少不顺手.以前写的外挂也都是手工 ...
- 四、testNG.xml 简单介绍
TestNG定义了一套非常具体的术语描述测试. testng.xml testng.xml是一个以XML记录所有测试的文件.可以利用这个文件,跑同一个类或者多个不同类里面的测试用例. testng.x ...
- AWT03-LayoutManager布局管理器
1.LayoutManager布局管理器 在之前的学习中,我们使用setBounds()方法设置容器的位置大小,但我们不得不明白一件事--如果我们手动为容器设置位置大小的话,就会造成程序通用性的下降. ...
- [日常摸鱼]pojKaka's Matrix Travels-拆点+最大费最大流
方格取数的升级版,每个格子最多取一次. $k=1$的话就是个普及组的dp题,$k=2$就是在之前的基础上多加两维. 然而现在$k$太大了当然就不dp啦 对于$k=1$的情况我们还可以把$(i,j)$向 ...
- 【JVM】类加载时机与过程
虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制.下面来总结梳理类加载的五个阶段. 类加载发生在 ...
- CTF练习 ①
最近学校要打比赛,,,把我这个混子也给算上了,,不得不赶紧学习学习. 今天学习的是SQL注入的一道题,参考的文章是 https://blog.csdn.net/qq_42939527/article ...
- metinfo小于v6.2.0版本SQL盲注利用脚本
#coding=utf-8 import requests import re import sys import time #获取config_safe.php中的 key def getKey(u ...
- iNeuOS工业互联平台,图表与数据点组合成新组件,进行项目复用
目 录 1. 概述... 1 2. 演示信息... 2 3. 应用过程... 2 1. 概述 针对有些行业的数据已经形成了标准化的建模或者有些公司专注于某 ...
- java基础:详解类和对象,类和对象的应用,封装思想,构造方法详解,附练习案列
1. 类和对象 面向对象和面向过程的思想对比 : 面向过程 :是一种以过程为中心的编程思想,实现功能的每一步,都是自己实现的 面向对象 :是一种以对象为中心的编程思想,通过指挥对象实现具体的功能 1. ...
- python字符串、列表通过值找索引/键
python透过"值"找字符串和列表中的索引和键. 1 #!usr/bin/env python3 2 #-*- coding=utf-8 -*- 3 4 ''' 5 python ...