操作系统实验4 LRU算法模拟

【实验名称】LRU算法模拟                    

 

【实验目的】

1.、通过请求页式存储管理中页面置换算法模拟设计

2、了解虚拟存储技术的技术特点

3、掌握请求页式虚拟管理的页面置换算法。

 

【实验原理】

最近最久未使用(LRU)的页面置换算法是根据页面调入内存后的使用情况做出决策的。由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似,因此,LRU置换算法是选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间t。当需要淘汰一个页面时,选择现有也面中t值最大的,即最近最久未使用的页面予以淘汰。

 

【实验内容】

实验内容:用C++模拟页面置换算法LRU,加深对LRU算法的认识。

代码(详情见代码注释):

#include
using namespace std;
//内存块类
class memory
{
public:
	void init();
	void alter(int a, int b);
	int check_full();
	int check_old();
	int check_exist(int a);
	void run();
	void refresh();
	friend int manage(memory *My_Memory, int ans, int a);
	friend void show(memory *My_Memory, int ans);
private:
	int page;
	int time;
};
//为了多次初始化
void memory::init()
{
	page = 0;
	time = 0;
}
//修改内存块保存的页和时间
void memory::alter(int a, int b)
{
	page = a;
	time = b;
}
//检查该块是否已被占用
int memory::check_full()
{
	if (page == 0 && time == 0)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
//检查该块的驻留时间
int memory::check_old()
{
	return time;
}
//检查该块中是否保存了页a
int memory::check_exist(int a)
{
	if (page == a)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
//时间++
void memory::run()
{
	if (page != 0)
	{
		time++;
	}
}
//时间置0
void memory::refresh()
{
	time = 0;
}
//调度作业
int manage(memory *My_Memory, int ans, int a)
{
	//检查内存块是否已经保存了页面a
	for (int i = 0; i < ans; i++)
	{
		if (My_Memory[i].check_exist(a))
		{
			cout << "不发生中断,页面" << a << "已在内存块" << i << "中" << endl;
			My_Memory[i].refresh();
			return 1;
		}
	}
	//检查内存块是否有空闲页面
	for (int i = 0; i < ans; i++)
	{
		if (My_Memory[i].check_full())
		{
			cout << "发生中断," << "内存块" << i << "空闲中,页面" << a << "装入" << endl;
			My_Memory[i].alter(a, 0);
			return 0;
		}
	}
	//找到驻留时间最大的块,进行替换
	int max_time = 0;
	int num = -1;
	for (int i = 0; i < ans; i++)
	{
		if (My_Memory[i].check_old()>max_time)
		{
			max_time = My_Memory[i].check_old();
			num = i;
		}
	}
	cout << "发生中断," << "内存块" << num << "中页面" << My_Memory[num].page << "被替换,页面" << a << "装入" << endl;
	My_Memory[num].alter(a, 0);
	return 0;
}
//显示内存块当前状态
void show(memory *My_Memory, int ans)
{
	cout << "...................................." << endl;
	cout << "内存块号";
	for (int i = 0; i < ans; i++)
	{
		cout << "  |" << i;
	}
	cout << "\n页面号  ";
	for (int i = 0; i < ans; i++)
	{
		cout << "  |" << My_Memory[i].page;
	}
	cout << "\n驻留时间";
	for (int i = 0; i < ans; i++)
	{
		cout << "  |" << My_Memory[i].time;
	}
	cout << "\n....................................\n" << endl;
}
int main()
{
	cout << "***************************" << endl;
	cout << "***   页面置换算法LRU   ***" << endl;
	cout << "*** 1.设置存储区块数    ***" << endl;
	cout << "*** 2.页面调度模拟      ***" << endl;
	cout << "*** 3.缺页率统计        ***" << endl;
	cout << "*** 4.退出模拟器        ***" << endl;
	cout << "***************************" << endl;
	int ans, aans = 0, nohit = 0;
	memory My_Memory[100];
	int flag;
	while (true)
	{
		cout << "\n请选择功能:";
		cin >> flag;
		if (flag == 1)
		{
			//设置存储区块数
			cout << "请输入存储区块数:";
			cin >> ans;
			for (int i = 0; i < ans; i++)
			{
				My_Memory[i].init();  
			}
			nohit = 0;
			aans = 0;
		}
		else if (flag == 2)
		{
			//页面调度模拟
			while (true)
			{
				for (int i = 0; i < ans; i++)
				{
					My_Memory[i].run();
				}
				cout << "请输入要调入的页面(输入0结束):";
				int a;
				cin >> a;
				if (a == 0)
				{
					break;
				}
				aans++;
				if (!manage(My_Memory, ans, a))
				{
					nohit++;
				}
				show(My_Memory, ans);
			}

		}
		else if (flag == 3)
		{
			//缺页率统计
			cout << "*****************" << endl;
			cout << "调度作业 " << aans << "次\n中断     " << nohit << "次\n缺页率   " << double(nohit) / aans * 100.00 << "%" << endl;
			cout << "*****************" << endl;
		}
		else if (flag == 4)
		{
			//退出
			cout << "成功退出!\n" << endl;
			break;
		}
	}
	return 0;
}

运行演示:

操作系统实验4 LRU算法模拟_第1张图片

操作系统实验4 LRU算法模拟_第2张图片

 

【小结或讨论】

LRU算法其实是比较容易理解的,它的核心思想就是:“由于无法预测各页面将来的使用情况,只能利用‘最近的过去’作为‘最近的将来’的近似”。在内存没有空闲且所要调入的内存块不在内存中的情况下,把最近最久未使用的页面调出内存再把新页面装入。

实验总体来说还是较为顺利的,既然规定要用C++来写,我就把内存块写成了一个类,并给它加上了void init();void alter(int a, int b); int check_full();int check_old();int check_exist(int a); void run();void refresh()等函数,方便调度函数int manage(memory *My_Memory, int ans, int a)的调用。由于page和time是类的私有成员变量还需声明了友元函数。

LRU算法的核心,就在于manage函数,这个判断的顺序就很重要。我们首先要判断的是我们要调入的页面是否已经在内存中,如果不在,我们则要判断内存中是否存在空闲,如果不存在,最后再根据最近最久未使用原则进行内存块的替换。只要这个判断顺序捋清了,整体问题也就不大了。

 

你可能感兴趣的:(操作系统实验)