LRU算法详解

在操作系统中,我们有的时候内存中的空间不够了,这个时候我们有新的作业要进入内存中,被调度运行,那该怎么办呢,我们有几种策略。

其一是随机置换策略,即当新的作业到来的时候,随机选择物理内存中的某个没有正在进行的作业,然后将其置换出去

其二是选择后面的某一段时间内,最久不会涉及到的内存块,可能是在1k条指令后才会访问,可能是1w条指令后才访问的块等

其三是先进先出的策略,即最先进入内存块的作业,在发生内存不足的情况下就最先离开。

其四是我们这一次要贴代码的LRU算法,他的策略是选择前面一段时间内最久没有被使用的物理页面,将其置换出去。因此我们需要给其加上一个时间戳。详情戳下面链接

百度百科–页面置换算法

下面是我贴上的代码,我采用的数据结构是链表形式,比较自由方便

LRU源代码:
#include <iostream>
#include <stdio.h>
#include <queue>
#include <ctime>
#include <set>
#include <stdlib.h>
#define MAX 10//十个物理内存块
#define N 20
using namespace std;
class block
{
	public:
	int id;
	clock_t last_time;
	block* next;
	block();
	block(int ID,clock_t c)
	{
		id=ID;
		last_time=c;
		next = NULL;
	}
};
class link
{
	public:
	int size;
	block* head;
	block* tail;
	block* curr;
	link()
	{
		size=0;
		head = new block(0,(clock_t)0);
		tail = head;
		curr = head;
	}
	block* remove();
	void add(block* b);
	block* find(int id);
	void print(clock_t);
};
//移出最久未访问的作业
block* link::remove()
{
	block* min = head->next;
	int i;
	curr = head->next;
	for(i=0;i<size;i++)
	{
		if(min->last_time>curr->last_time)min=curr;
		curr = curr->next;
	}
	return min;
}
//初始化的时候添加作业
void link::add(block* b)
{
	tail->next = b;
	tail = tail->next;
	size++;
}
//查找在当前链表里面有没有某个作业
block* link::find(int id)
{
	block* index;
	for(index=head->next;index!=NULL;index=index->next)
	{
		if(index->id==id)
		return index;
	}
	return NULL;
}
//打印操作,将物理内存块的情况打印出来
void link::print(clock_t st)
{
	curr = head->next;
	int i=0;
	cout<<"编号:   页号   上一次访问时间"<<endl;
	while(curr!=NULL)
	{
		cout<<"  "<<i<<"   "<<curr->id<<"           "<<(curr->last_time-st)/CLOCKS_PER_SEC<<endl;
		i++;
		curr=curr->next;
	}
	cout<<"规模为: "<<size<<endl;
}
set<int> my_set;
//查找某个作业是否在里边,我们可以用set来查找,set底层是RB-Tree,查找会比较快
//初始化的时候用的
bool search(int x,set<int> my_set)
{
	set<int>::iterator iter;
	iter = my_set.find(x);
	if(iter!=my_set.end())
	return true;
	return false;
}
int main()
{
	srand(time(NULL));
	int i,j,k;
	link* mylink = new link();
	clock_t st = clock();
	//Init
	int tmp_init=rand()%MAX;//随机产生tmp_init个作业
	int tmp_rand;
	
	for(i=0;i<tmp_init;i++)
	{
		tmp_rand=rand()%N;	//随机产生作业号并且要查重,防止同样的作业
		while(search(tmp_rand,my_set)==true)
		{
			tmp_rand=rand()%N;	
		}
		my_set.insert(tmp_rand);	//将作业ID插入集合
		mylink->add(new block(tmp_rand,clock()));	//将作业装入链表里面进行管理
	}
	mylink->print(st);
	int n,tmp_id;
	block* tmp_block1;
	block* tmp_block2;
	cout<<"请输入需要操作的次数n"<<endl;
	cin>>n;
	for(i=0;i<n;i++)
	{
		cout<<"请输入需要访问的逻辑页面tmp_id"<<endl;
		cin>>tmp_id;	//输入你需要访问的id
		tmp_block1=mylink->find(tmp_id);
		if(tmp_block1!=NULL)	//如果找到,即不为空,那就修改那个块的最后一次时间
		{
			tmp_block1->last_time=clock();
		}
		else if(tmp_block1==NULL)	//如果为空,说明链表里没这个作业
		{
			if(mylink->size>=MAX)//如果作业量已经超过最大容量,就按照LRU剃掉一个
			{
				tmp_block2=mylink->remove();
				tmp_block2->id=tmp_id;
				tmp_block2->last_time=clock();
			}
			else	//如果没有超过最大容量,就添加一个作业放在后面
			{
				mylink->add(new block(tmp_id,clock()));
			}
		}
		mylink->print(st);
	}
	return 0;
}

以上是我写的C++的LRU页面置换算法,有bug或者不对的地方欢迎指正
另外,后期应该会推出关于内存分配与内存管理的博文以及相关代码。包含内存分配,分页式管理,多层索引等等,有需要的可以联系下面邮箱。
------------------------------1124397151@qq.com-------------------------------------

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值