LRU调度算法

LRU:Least Recently Used
中文名:最近最久未使用调度算法

定义

什么是LRU?
它是按照一个非常著名的计算机操作系统基础理论得来的:最近使用的页面数据会在未来一段时期内仍然被使用,已经很久没有使用的页面很有可能在未来较长的一段时间内仍然不会被使用。 基于这个思想,会存在一种缓存淘汰机制,每次从内存中找到最久未使用的数据然后置换出来,从而存入新的数据!它的主要衡量指标是使用的时间,附加指标是使用的次数。在计算机中大量使用了这个机制,它的合理性在于优先筛选热点数据,所谓热点数据,就是最近最多使用的数据!因为,利用LRU我们可以解决很多实际开发中的问题,并且很符合业务场景。
简而言之,LRU调度算法每次淘汰的是最近最久未使用的页面,它不会出现像FIFO算法那样并不是每次都是淘汰最老页面,LRU算法淘汰的永远是最近最久未使用的页面,当访问到一个已存在于缓存队列中的页面时,与FIFO调度算法不同的是它会把访问到的页面移到队尾,即重新对队列进行排序。当访问到已存在于缓存中的页面且处在队尾时,保持队列不变。除此之外,都要将队列进行重新排序,将访问到的页面设置为最新页面(即队尾位置)。
定义部分来源

定义过于抽象,下面通过一个实例来更加深刻了解LRU算法

假设缓存大小为3,访问页面顺序为2,6,4,8,5,4,1,4,6,3,9。

可以观察与FIFO调度算法不同之处

->2
->6 2
->4 6 2
->8 4 6
->5 8 4
->4 5 8 4调入内存,但4已经存在,故内存结构发生变化
->1 4 5
->4 1 5 4调入内存,但4已经存在,故内存结构发生变化
->6 4 1
->3 6 4
->9 3 6

C语言代码

#include<stdio.h>
#define MAX 3//缓存最大页面容量 
typedef struct lru{
	int lru[MAX];//存放页面号 
}LRU;

int main()
{
	int temp = -1;//充当中间变量,暂时缓存一个值 
	int flag = 0;//0表示访问的这个页面是一个新页面,1表示访问的这个页面已存在于缓存中 
	int data;//页面号 
	int mid;//充当中间变量,暂时缓存一个值 
	LRU L;
	for(int i = 0; i < MAX; i++)
	{
		L.lru[i] = -1;
	}
	for(int i = 0; i < MAX; i++)
	{
		flag=0;
		printf("请输入第%d个页面号:",i);
		scanf("%d",&data);
		for(int j = 0; j < MAX; j++)
		{
			if(data == L.lru[j])//如果这个页面已存在于缓存中 
			{
				flag = 1;
				temp = j; 
			} 
		}
		if(flag != 1)//如果这个页面不存在于缓存中 
		L.lru[i] = data;
		else//如果这个页面已存在于缓存中 
		{
			printf("你输入的页面已存在,已更新你的访问缓存!\n");
			if( i-temp != 1 )//temp就是j 
			{
				for(int d = 0; d < i-1; d++)
				{
					L.lru[d] = L.lru[d+1];
					if(d+1 == i-1)
					{
						L.lru[d+1] = data;
						break;
					}
				
				}
			}
			printf("\n");
			for(int s = i-1; s >= 0; s--)
			printf("第%d个页面-> %d\n",s,L.lru[s]);
			printf("\n");
			i--;
		}
		
	}
	printf("开始页面分别为\n");
	printf("\n");
	for(int i = MAX-1; i >= 0; i--)
	printf("第%d个页面-> %d\n",i,L.lru[i]);
	printf("\n");
	
	while(true)//已存在3个元素,每输入一个元素都进行一次比较 
	{
		flag = 0;
		printf("请输入一个新的页面:");
		scanf("%d",&data);
		for(int i = 0; i < MAX; i++)
		{
			if(data == L.lru[i])//如果这个页面已存在于缓存中 
			{
				flag = 1;
				mid = i;//缓存已存在于缓存中的页面地址 
			}
		}
		if(flag == 1)//如果这个页面已存在于缓存中 
		{
			if( !(mid+1 == MAX) )
			for(int i = mid; i < MAX-1; i++)//MAX是因为这里输入的数据是data  ?
			{
				L.lru[i] = L.lru[i+1];
				if(i+1 == MAX-1)
				{
					L.lru[i+1] = data;
					break;
				}
			}
		}
		else//如果这个页面不存在于缓存中 
		{
			for(int i = 0; i < MAX-1; i++)//MAX-1是因为数组存储页面号的最后一个是在MAX-1上,而输入的data相当于是在MAX位置上 
			{		   //比如MAX=3,那么它交换数据时是->  0<--1; 1<--2; 2<--MAX 一共两次循环,最后一次循环执行最后两句 
				L.lru[i] = L.lru[i+1];
				if(i+1 == MAX-1)
				{
					L.lru[i+1] = data;
					break; 
				}
			}
		}
		printf("换替换后的页面结果为\n");
		printf("\n");
		for(int i = MAX-1; i >= 0; i--)
		printf("第%d个页面-> %d\n",i,L.lru[i]);
		printf("\n");
	}
	return 0;
}

执行结果

请输入第0个页面号:5
请输入第1个页面号:6
请输入第2个页面号:5
你输入的页面已存在,已更新你的访问缓存!

第1个页面-> 50个页面-> 6

请输入第2个页面号:6
你输入的页面已存在,已更新你的访问缓存!

第1个页面-> 60个页面-> 5

请输入第2个页面号:4
开始页面分别为

第2个页面-> 41个页面-> 60个页面-> 5

请输入一个新的页面:6
换替换后的页面结果为

第2个页面-> 61个页面-> 40个页面-> 5

请输入一个新的页面:5
换替换后的页面结果为

第2个页面-> 51个页面-> 60个页面-> 4

请输入一个新的页面:3
换替换后的页面结果为

第2个页面-> 31个页面-> 50个页面-> 6

请输入一个新的页面:

总的来说,这个算法也比较简单,但它同FIFO算法比较有明显的改进,可以理解为是FIFO的改进版。作者用的是结构体实现。
本人菜鸟一枚妥妥,可能代码写的不规范也可能代码有冗余存在,或者定义出现的名词不规范等问题,欢迎各位大佬指教。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

eeeasyFan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值