LRU算法实现

前言

最近最久未使用(LRU)置换算法原理就是当需要淘汰某页面时,选择当前一段时间内最久未使用过的页先淘汰,即淘汰距当前最远的上次使用的页。

1. LRU设计要求

假定分配给该进程的页块数为3,页面访问序列长度为20,首先随机产生页面序列,当发生请求调页时,若内存已满,则需要利用LRU算法,将当前一段时间内最久未使用过的页替换出去。

2. 源程序使用的数据结构和符号说明

通过一个结构体LRU包含整个LRU的具体实现,设计另外一个结构体LRU_node,该结构体包含int型的两个变量key和value,key表示节点最后一次出现的序号,相当于记录时间,value代表节点的权值,这里是记录访问页面的页面号。结构体LRU中数组arr[]存储页面访问序列,数组vids[]初值全设为0,vids[i]主要用来判断当前访问序列中的某个页面号为i的页面arr[i]是否存在在该进程所分配的页块中,vids[i]为0证明当前进程所拥有的页块中并没有该页面,此时缺页,缺页次数count加一,然后把页块中拥有最小key值的页面给替换出去,这就达到了淘汰距当前最远的上次使用的页这一目的,替换完成后然后利用我们自定义的排序算法根据页面达到的时间按照从小到大排序; vids[i]为1则证明当前进程所拥有的页块存在该页面,此刻只需要改变该页面的key值即可,然后也进行重新按照时间到来顺序排序。最后计算出缺页次数和缺页率即可。

3.具体实现

#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>

#define max_size 100

using namespace std;
/**
 * LRU算法的实现:可以使用一个结构体,来储存对应的数据
 * 那么使用一个vector动态数组来储存当前的物理块中的内容
 * 那么每访问一次就更新结构体中的value值,那么对vector数组
 * 进行对应sort排序,即按照value从大到小排序,然后每次弹出队尾
 * 将最小的value值的结构体弹出
 * 测试数据如下
20 3
1 2 5 6 0 3 6 5 3 6 5 6 0 4 2 7 0 4 3 5
 * **/
struct LRU_node{//LRU的节点结构
    int key, value;//key代表节点最后一次出现的序号,value代表节点的权值
};
bool cmp(const LRU_node &a, const LRU_node &b){
    return a.key > b.key;//排序,自定义排序cmp方法
}
struct LRU{
    int arr[max_size];//arr即存储当前的数据
    vector<LRU_node>vec;//动态数组储存节点
    int vids[max_size];//标记数组
    void Init(){//清空函数
        memset(vids, 0, sizeof(vids));
        memset(arr, 0, sizeof(arr));
        vec.clear();
    }

    void slove(){
        cout <<"请输入页面访问序列长度:";
        int n, m;
        cin>>n;;
        cout <<"请输入页块数:";
        cin>>m;             //n 代表输入的序列的长度是多少, m代表物理块的大小
        cout << "请输入页面访问序列:";
        for(int i = 0; i < n; i++){
            cin>>arr[i];                         //输入页访问序列
        }
        cout << endl;
        int count = 0;//缺页数
        int r = 0;//遍历边界

        while(r < n){
            LRU_node a;
            a.key = r;
            a.value = arr[r];//获取一个节点
            if( !vids[a.value] ){//物理块中没有这个数
                count ++;//缺页数加一

                if(vec.size() < m){//vec的数量小于物理块m
                    vec.push_back(a);
                    vids[a.value] ++;//标记块中出现的数
                    sort(vec.begin(), vec.end(), cmp);//排序,保证弹出的肯定是时间最开始的那个
                }
                else{//vec的数量等于物理块的大小
                    sort(vec.begin(), vec.end(), cmp);//排序
                    LRU_node en = vec[vec.size() - 1];//取出最后的那个即时间最开始的那个
                    vids[en.value] --;//把弹出的数去掉
                    vec.pop_back();
                    vec.push_back(a);//把新的值压入vec
                    vids[a.value] ++;//标记新的值在块中出现
                    sort(vec.begin(), vec.end(), cmp);///排序
                }
                for(int i = 0; i < vec.size(); i ++){
                    cout << vec[i].value << " ";
                }
                cout << "缺页" << endl;
            }
            else{//否则在块中有对应的数
                for(int i = 0; i < vec.size(); i ++){//遍历块中数据
                    if(vec[i].value == a.value){
                        vec[i].key = a.key;//更新块中的数据所对应的key值,即出现的最后的时间
                        break;
                    }
                }
                sort(vec.begin(), vec.end(), cmp);//排序
                for(int i = 0; i < vec.size(); i ++){
                    cout << vec[i].value << " ";
                }
                cout << endl;
            }
            r++;
        }
        cout << "缺页次数:" << count << endl << "缺页率:" << count <<'/'<<n<<"="<<(count*1.0)/20 << endl;
    }
};
int main(){
    LRU solution;
    solution.Init();
    solution.slove();
    return 0;
}

4.示例

在这里插入图片描述

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值