三种页面置换算法

  这次要写的是三种页面置换算法,最佳置换算法、先进先出算法和最近最久未使用算法。这里只是大概介绍一下每个算法,和自己编程的思想。如果看的感觉比较模糊,可以网上百度一下“页面置换算法”具体看一看,我就不再把那些东西再搬过来了。


最佳置换:

最佳置换算法只是一种理论上的算法,因为要使用未来的数据来判断现在该置换哪个物理块是最佳的,所以实际上是不能实现的,因为我们无法预知未来的数据。所以它最大的用处是用来检验算法的优劣性。


这是最佳置换的具体过程模拟,第一行是将要置换到内存的页号顺序。第3~5行是假设的三个内存物理块,用来存放置换的页面(-1表示物理块为空)。刚开始都没有使用过,所以前三个页号,7 0 1 依次放到三个物理块中。现在轮到第四个页号2,我们根据最佳置换原则,第5个页号是0,第14个页号是1,第18个页号才是7,所以7是未来最久才会用到的页号,所以第四轮把7置换掉,物理块由7 0 1变为2 0 1,以后都是按这个原则来置换。下面是c++代码:
#include <iostream>
/*#include <iterator>
#include <algorithm>
#include <vector>*/
using namespace std;

int main()
{
	const int Nmax = 20;
	const int Kmax = 3;
	int num[Nmax] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };//页面号
	int kuai[Kmax] = { -1, -1, -1 };//3个物理块,-1表示空
	int i, j, k, count, m, count2, count3;
	i = j = k = count = count2 = count3 = m = 0;
	int Nsort[3] = { 100, 100, 100 };
	int sortMax;
	for (i; i < Nmax; ++i)  //从i=0即7开始放入物理块
	{
		cout << "当前物理块中的数据(第" << i << "次):";
		for (k = 0; k < Kmax; ++k)
		{
			cout << kuai[k] << " ";
		}
		cout << endl;


		for (k = 0; k < Kmax; ++k)//先查看是否有空位
		{
			if (kuai[k] == -1)
			{
				kuai[k] = num[i];
				count = 1;
				count2 = 1;
				break;
			}
		}
		if (count == 1)//当count=1时表示刚才那个数已经填到空位里去了,这时剩下的循环要结束,i++进行下一个
		{
			count = 0;
			continue;
		}//检查空位结束
		for (k = 0; k < Kmax; ++k)
		{
			if (kuai[k] == num[i])
			{
				count = 1;
				count3 = 1;
				break;
			}
		}
		if (count == 1)//当count=1时表示当前的num[i]已经在块中,提前结束循环,i++
		{
			count = 0;
			continue;
		}
		if (i < Nmax - 1)//限制m不能超过Nmax
		{
			for (k = 0; k < Kmax; k++)//找未来最久不会出现
			{
				for (m = i + 1; m < Nmax; ++m)
				{
					if (kuai[k] == num[m])
					{
						Nsort[k] = m;
						break;
					}
				}
			}
		}
		/*if (count2 == 1)//结束最外层循环,i++
		{
		count2 = 0;
		continue;
		}
		if (count3 == 1)//结束最外层循环,i++
		{
		count3 = 0;
		continue;
		}*/
		sortMax = Nsort[0];
		for (k = 0; k < Kmax; ++k)//找出最久不会出现的页面号
		{
			if (sortMax < Nsort[k])
			{
				sortMax = Nsort[k];
			}
		}
		if (sortMax == 100)
		{
			sortMax = 0;
		}
		if (sortMax == 101)
		{
			sortMax = 1;
		}
		if (sortMax == 102)
		{
			sortMax = 2;
		}
		for (k = 0; k < Kmax; ++k)
		{
			if (kuai[k] == num[sortMax])
			{
				sortMax = k;
				break;
			}
		}
		kuai[sortMax] = num[i];
		Nsort[0] = 100;
		Nsort[1] = 101;
		Nsort[2] = 102;

	}
	system("pause()");
	return 0;
}

先进先出:

先进先出的思想是三个物理块按先后顺序,最先置换过的物理块也最先置换进去,像一个排队的过程一样。


这里和上一个图片有一点区别,多了7~9行一些奇怪的数字。解释一下,这个是我无意中发现的一个规律。每次置换页面的时候置换掉值为1的那个物理块,然后3个物理块每个块的值减一,值为1的那个物理块值变成3。要置换的页面号在物理块中时则不做任何改变。于是按这个规律,第四轮置换页面号为2,不在物理块内,置换掉值最先进入(第一轮)的7。物理块由 7 0 1 变为了2 0 1.后面同理。下面是c++代码:
#include <iostream>
using std::cin;
using std::cout;
using std::endl;

const int Nmax = 20;//页面号数量
const int Kmax = 3;//物理块数量

bool IsIn(const int *kuai,const int &num)
{
	int i;
	for (i = 0; i < Kmax; ++i)
	{
		if (kuai[i] == num)
			return true;
	}
	return false;
}

void NoIn(int *kuai,int *kuai2,const int &num)
{
	int i,loc;
	for (i = 0; i < Kmax; ++i)
	{
		if (kuai2[i] == 1)
		{
			kuai[i] = num;
			loc = i;
		}
		kuai2[i] -= 1;
	}
	kuai2[loc] = 3;
}

int main()
{
	int num[Nmax] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };//页面号
	int kuai[Kmax] = { -1, -1, -1 };//3个物理块,-1表示空
	int kuai2[Kmax] = { 1, 2, 3 };//保存每个块的先后顺序,3是刚进的,1是最早进马上要置换的。初始三个块为空
	int i,j;
	cout << "第" << 0 << "次:";
	for (j = 0; j < Kmax; ++j)
		cout << kuai[j] << " \t";
	cout << endl;
	for (i = 0; i < Nmax; ++i)//最外层循环,对页面号置换依次循环
	{
		
		if (IsIn(kuai, num[i]))//先检查是否在物理块内
			continue;//如果在内,不用做任何改变
		else
			NoIn(kuai,kuai2,num[i]);//不在物理块内
		cout << "第" << i+1 << "次:";
		for (j = 0; j < Kmax; ++j)
			cout << kuai[j] << " \t";
		cout << endl;
	}
		
	system("pause()");
	return 0;
}

最近最久未使用:

最近最久未使用,也就是字面意思,其实它和先进先出很像,唯一会出现不同的地方就是当要置换的页面号已经在物理块内的时候,物理块内容不变,但是,这个页号被认为刚被使用过一次。当不在物理块内的时候,则置换掉最久没有使用的一个物理块。


如图,其实过程和先进先出差不多,也多了7~9行,只需要稍微改进一下那个规律。当要置换的页面号已经在物理块内的时候,物理块内容不变,但是保存该页面号的那个物理块的值要改为3,其他两个物理块值减1,如果原来本来就是1则不变,如果要置换的页面号那个物理块本来就是3则也不变。下面是c++代码:
#include <iostream>
using std::cin;
using std::cout;
using std::endl;

const int Nmax = 20;//页面号数量
const int Kmax = 3;//物理块数量


bool Inkuai(const int &num,int *kuai,int &loc)//首先检查要换进的页面号是否在物理块中,如果在,用loc返回索引
{
	int i;
	for (i = 0; i < Kmax; i++)
	{
		if (num == kuai[i])
		{
			loc = i;
			return true;
		}
	}
	return false;
}

void IsIn(int *kuai2,const int loc)//在物理块内
{
	int i;
	for (i = 0; i < Kmax; ++i)
	{
		if (loc == 2)//在物理块的页面号本来就是刚使用过的时,不要改变
			break;
		if (kuai2[i] == 1)
			continue;
		kuai2[i] -= 1;
	}
	kuai2[loc] = 3;
}

void NoIn(int *kuai,int *kuai2,const int &num)//不在物理块内
{
	int i,loc;
	for (i = 0; i < Kmax; ++i)
	{
		if (kuai2[i] == 1)
		{
			kuai[i] = num;
			loc = i;
		}
		kuai2[i] -= 1;
	}
	kuai2[loc] = 3;
}

int main()
{
	int num[Nmax] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };//页面号
	int kuai[Kmax] = { -1, -1, -1 };//3个物理块,-1表示空
	int kuai2[Kmax] = { 1, 2, 3 };//保存每个块的先后顺序,3是刚进的,1是最早进马上要置换的。初始三个块为空
	int i,loc,j;
	for (i = 0; i < Nmax; ++i)//最外层循环,页面号一个一个进来
	{//1
		cout << "第" << i  << "次:";
		for (j = 0; j < Kmax; ++j)
		{
			cout << kuai[j] << " \t";
		}
		cout << endl;
		loc = -1;//如果在物理块内,用来保存其索引
		if (Inkuai(num[i], kuai,loc))//先判断置换号是否在物理块内
			IsIn(kuai2,loc);//在物理块内,不用置换,但先后顺序要变
		else
			NoIn(kuai, kuai2,num[i]);//不在物理块内,要置换,而且改变先后顺序
	}//1
	system("pause()");
	return 0;
}



评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值