页面置换算法——最近最久未使用算法(C语言实现)

操作系统实验:用C语言编程实现最近最久未使用置换算法(LRU)

最近最久未使用置换算法(LRU),全称Least Recently Used,是一种页面置换算法。

对于在内存中但又不用的数据块(内存块)叫做LRU,操作系统会根据哪些数据属于LRU而将其移出内存而腾出空间来加载另外的数据。

简单概括其思想:

1.根据页面调入内存后的使用情况。
2.利用“最近的过去”作为“最近的将来”的近似。
3.选择最近最久未使用的页面予以淘汰。

 一般有3种方法

1.数组+时间戳

2.栈

3.队列

 其中栈和队列可以选择顺序型或者是链型。

手工栈和队列代码冗长,顺序栈和顺序队列不方便从中间改动数据。链型初始化较麻烦,且考虑细节较多。主要介绍数组+时间戳法。

算法思路:

用一个数组来存储数据,给每一个数据项标记一个访问时间戳,每次插入新数据项的时候,先把数组中存在的数据项的时间戳自增,并将新数据项的时间戳置为0并插入到数组中。每次访问数组中的数据项的时候,将被访问的数据项的时间戳置为0。当数组空间已满时,将时间戳最大的数据项淘汰。

所以要用此方法,必须定义一个二维数组或者是结构体,我结合了时间戳、栈和顺序表的思路,重新设计了一个较好的方法。

代码如下:

#include<stdio.h>
#define MAX 100

int judge(int a[],int n,int x)		//判断数组中是否已有x,若有返回其下标值,没有则返回-1 
{
	int i;
	for(i=0;i<n;i++)
		if(x==a[i])
			return i;
	return -1;
}

void init(int a[],int n)		//初始化数组为-1 
{
	int i;
	for(i=0;i<n;i++)
		a[i]=-1;
}

void insert(int a[],int n,int x)	//栈法插入(第一个元素出,后面元素前移,新元素从尾部入) 
{
	int i;
	for(i=0;i<n-1;i++)
		a[i]=a[i+1];
	a[n-1]=x;
}

void move(int a[],int n,int i)		//移动下标为i的元素到尾部 
{
	int j;
	int m=a[i];
	for(j=i;j<n-1;j++)
		a[j]=a[j+1];
	a[n-1]=m;
} 

void print(int a[],int n)		//输出当前数组元素 
{
	int i;
	for(i=0;i<n;i++)
		if(a[i]!=-1)
			printf(" %d",a[i]);
	printf("\n");
}

int main()
{
	int stack[MAX];
	int top=-1;			//模仿栈的定义 
	int n,x;
	printf("请输入物理块数:\n");
	scanf("%d",&n);		 
	init(stack,n);			//初始化数组 
	printf("请输入内存访问序列:\n");
	while(~scanf("%d",&x))		//自动读数 
	{
		printf("访问页面%d:\n",x);
		top++;			//读数后top自动+1 
		if(top==0)		//若数组无元素
			stack[top]=x;	//插入一个元素 
		else if(top<n)		//若在物理块范围内 
		{
			if(judge(stack,n,x)==-1)//若数组中不存在待插入元素 
				stack[top]=x;	//新元素从尾部插入 
			else			//若数组中存在待插入元素
			{
				move(stack,top,judge(stack,n,x));//移动下标为i的元素到尾部 
				top--;				//因为没有插入新元素,回滚top值 
			}
		}		
		else				//超过物理块数的元素 
		{
			if(judge(stack,n,x)==-1)//若数组中不存在待插入元素
			{
				insert(stack,n,x);	 //栈法插入(第一个元素出,后面元素前移,新元素从尾部入)
				top--;			//因为没有插入新元素,回滚top值
			}
			else				//若数组中存在待插入元素
			{
				move(stack,n,judge(stack,n,x));//移动下标为i的元素到尾部
				top--;			//因为没有插入新元素,回滚top值 
			}
		}
		print(stack,n);				//读一个序列号,输出当前数组元素 
	}
	
	return 0;
}

  

运行结果:

操作系统确实博大精深,想想当初开发操作系统的计算机先驱们真是伟大,一点点从硬件层开发到软件层,这期间遇到了多少问题,耗费了多少精力,再次膜拜他们~

果然只有自己动手把代码敲出来才算真正理解了一个算法,学编程一定要动手,不怕难,多思考,才能进步啊~ 

posted @ 2018-11-27 01:54  望三星  阅读(9950)  评论(0编辑  收藏  举报