操作系统页面置换算法 ---之---FIFO置换算法、OPTIMAL置换算

                                 操作系统页面置换算法

                                            ---之---

                  FIFO置换算法、OPTIMAL置换算法、LRU置换算法

        页面置换算法在内存中没有空闲页面时被调用,其目的是选出一个被淘汰的页面,把内存和外存统一管理的目的是把那些访问概率高的页面放在内存,因此,页面置换算法因该置换那些访问概率低的页面,并把它们移除内存。

        当进程产生缺页中断时,若内存已经没有空闲区域时,为了保证进程能够正常运行,系统必须依据一定的算法从内存中选择某页程序(基于请求分页存储管理方式)或数据送到磁盘的交换区,所采用的算法即是页面置换算法。

        这里简单讲到三中简单的页面置换算法:FIFO置换算法、OPTIMAL置换算法、LRU置换算法

OPTIMAL置换算法(最佳置换算法)

        最佳置换算法是一种理想化的置换算法,其置换的页面将是以后永久不使用的,或是将来很长时间内不再使用的页面(代码中置换的是引用串中较长时间不适用的页面)。它可以保证最低的缺页率。

FIFO置换算法(先进先出置换算法)

        这种算法的出发点是先装入内存的页面先被置换。其总是先淘汰那些驻留时间最长的页面。

LRU置换算法(最近最久未使用置换算法)

        该算法根据页面调入内存后的使用情况进行决策。由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间T,当须淘汰一个页面时,选择现有页面中其T值最大的,即最近最久未使用的页面予以淘汰。

#include <iostream>
#define M 3  //物理块数 
#define N 20  //页面引用串长度 

using namespace std;

struct block
{
	int iPageNum;      //物理块里存储的页面号
	int iBlockFlag;		//在三种算法中用到的标记。例如在FIFO中为在内存中的时间
};
//算法模拟移位寄存器原理

void FIFO(int iTempPage[N],int flag[N],block myBlock[M]);//先进先出置换算法 
void Optimal(int iTempPage[N],int flag[N],block myBlock[M]);//最佳置换算法 
void LRU(int iTempPage[N],int flag[N],block myBlock[M]);//最近最久未使用置换算法 
int PageNum(int array[]);

int main()
{
	block myBlock[M]; 
	int iPageString[N]={7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};  
	//页面引用串

	int iTempPage[N]; //临时页面引用串
	int flag[N];      //缺页标记;1为缺页,0为不缺页,在统计缺页次数时用

	int i;

	bool bExitFlag=true;   //退出标记
  	char ch;		  //接收选择算法时传进来的值

	while(bExitFlag)
	{
		cout<<"\n"<<"请选择页面置换算法:\n";
	    cout<<"f:FIFO置换算法\to:OPT置换算法\tl:LRU置换算法\tx:退出置换算法程序.\n";
		cin>>ch;

		//初始化数据
		if((ch=='f')||(ch=='o')||(ch=='l')) 
		{
			for(i=0;i<N;i++)
			{
				iTempPage[i]=iPageString[i];  //初始化临时页面引用串
				flag[i]=0;                    //初始化缺页标记为0,即不缺页
			}
		}

		switch(ch)
		{  
		    case 'f':
		        cout<<"FIFO置换算法的结果是:\n";
                FIFO(iTempPage,flag,myBlock); 
				//用PageNum(flag)统计缺页次数
				cout<<"\n缺页次数为"<<PageNum(flag)<<endl;
				break;
	        case 'o': 
   		        cout<<"OPT置换算法的结果是:\n";
			    Optimal(iTempPage,flag,myBlock);  
				cout<<"\n缺页次数为"<<PageNum(flag)<<endl;
				break;
            case 'l':
   	            cout<<"LRU置换算法的结果是:\n";
 			    LRU(iTempPage,flag,myBlock);  
				cout<<"\n缺页次数为"<<PageNum(flag)<<endl;
			    break;
	        case 'x': 
			    cout<<"退出置换算法。\n";
			    bExitFlag=false; 
			    break;
		    default: 
		        cout<<"输入有误,请重新选择置换算法:\n";
		}
	}
	return 0;
}

//对数组中的数累加
int PageNum(int array[])
{
	int num=0;
	for(int j=0;j<N;j++)
		num=num+array[j];
	return num;
}

//定位函数,在最佳算法中用于定位;
//定位物理块中的某一个页面在引用串中还未访问串中页面的位置
int allocate(int iPage,int iLoc,int iTempPage[N])
{
	int i;
	for(i=iLoc;i<N;i++)
	{
		if (iPage==iTempPage[i])
			return i;
	}
	//永远不再访问的页面位置假定为N
	return N;
}

//找数组中最大值所在的下标,返回最大值在数组中的位置(下标)
int max(block array[M])
{
	int j,loc;
	int temp=array[0].iBlockFlag;
	loc=0;

	for(j=1;j<M;j++)
	{
		if (temp<array[j].iBlockFlag) 
		{
			temp=array[j].iBlockFlag;
			loc=j;
		}
	}
	return loc;
}
//输出剩余的数据
//loc为页面引用串中
void output(int iPage,int flag,block myBlock[M],int blockNum)
{
	int j;
	//如果缺页则输出缺页标志,否则不输出
	if (flag==1)
		cout<<"\n  "<<flag;
	else
		cout<<"\n  ";
	cout<<"\t  "<<iPage;
	for(j=0;j<blockNum;j++)
		cout<<"\t  "<<myBlock[j].iPageNum;	
}

//初始化物理块的内容,因任一种算法在物理块内容为空时,结果都一样的
//同时将目前物理块中的内容输出
void InitialBlock(int iTempPage[N],int flag[N],block myBlock[M])
{
	int i;
	for(i=0;i<M;i++)
	{
		//初始化物理块的内容,因任一种算法在物理块内容为空时,结果都一样的
		myBlock[i].iPageNum=iTempPage[i]; 
		//myBlock[i].iBlockFlag的值:0为最后进来的,数越大表示进来的越早
		//在最佳置换算法中则初始化此值没有意义
		myBlock[i].iBlockFlag=(M-1)-i;  
		flag[i]=1;   //此时为缺页
	}
	//输出
	cout<<"\n缺页\t引用串\t物理块1\t物理块2\t物理块3";
	for(i=0;i<M;i++)
		output(iTempPage[i],flag[i],myBlock,i+1);
}

//FIFO置换算法
void FIFO(int iTempPage[N],int flag[N],block myBlock[M])
{
	int i,j,k,loc;	
	bool ExistFlag=false;//退出标记

	//初始化物理块的内容,因任一种算法在物理块内容为空时,结果都一样的
	//同时将目前物理块中的内容输出
	InitialBlock(iTempPage,flag,myBlock);

	//从引用串中的第4个页面开始
	for(i=3;i<N;i++)
	{
		ExistFlag=false;
		for(j=0;j<M;j++)
		{
			//物理块中存在
			if (myBlock[j].iPageNum==iTempPage[i]) 
			{
				//模拟移位寄存器
				for(k=0;k<M;k++)
					myBlock[k].iBlockFlag++;//物理块中存在

				ExistFlag=true;
				flag[i]=0;
				break;
			}
		}
		//物理块中不存在
		if (!ExistFlag) 
		{
			//查找最先进来的页面,也就是block中iBlockFlag最大的物理块
			loc=max(myBlock);
			myBlock[loc].iPageNum=iTempPage[i];
			
			//置缺页标志
			flag[i]=1;

	// 将物理块中与引用串匹配的物理块的标记位置0,其余加1(模拟移位寄存器) 
			for(k=0;k<M;k++)
				if (k!=loc)			
					myBlock[k].iBlockFlag++;
				else
					myBlock[k].iBlockFlag=0;
		}
		
		//输出
		output(iTempPage[i],flag[i],myBlock,M);
	}
	cout<<endl;
}


//Optimal最佳置换算法
void Optimal(int iTempPage[N],int flag[N],block myBlock[M])
{
    int i,j,k,loc;	
	bool ExistFlag=false;//退出标记

	//初始化物理块的内容,因任一种算法在物理块内容为空时,结果都一样的
	//同时将目前物理块中的内容输出
	InitialBlock(iTempPage,flag,myBlock);
	
    for(i=3;i<N;i++)
	{
	    for(j=0;j<M;j++)
		{
			//物理块中存在 
			if(myBlock[j].iPageNum==iTempPage[i])
			{
				flag[i]=0;
				break;
			}
		}	
		//物理块中不存在 
		if(j==M)
		{
			for(j=0;j<M;j++)
			//定位物理块中的某一个页面在引用串中还未访问串中页面的位置,存入物理块标记 
			myBlock[j].iBlockFlag=allocate(myBlock[j].iPageNum,i+1,iTempPage);
			//找出标记最大的物理块 
			loc=max(myBlock);
			//换出操作 
			myBlock[loc].iPageNum=iTempPage[i]; 
			flag[i]=1;
		}
		output(iTempPage[i],flag[i],myBlock,M);
	 } 
	 
} 
//LRU置换算法
void LRU(int iTempPage[N],int flag[N],block myBlock[M])
{
	int i,j,k,loc;	
	bool ExistFlag=false;//退出标记

	//初始化物理块的内容,因任一种算法在物理块内容为空时,结果都一样的
	//同时将目前物理块中的内容输出
	InitialBlock(iTempPage,flag,myBlock);
	
	for(i=3;i<N;i++)
	{
		for(j=0;j<M;j++)
		{
			//物理块中存在 
			if(myBlock[j].iPageNum==iTempPage[i])
			{   
			    //将物理块中与引用串匹配的物理块的标记位置0,其余置1 (模拟移位寄存器)
				for(k=0;k<M;k++)
				    if(k==j)
					    myBlock[k].iBlockFlag=0;
					else
					    myBlock[k].iBlockFlag++;
				// 缺页标记 
				flag[i]=0;
				break;
			 } 
		}
		if(j==M)
		{
			//将物理块中标记值最大的物理块的下标找出 
			loc=max(myBlock);
			//换出操作 
			myBlock[loc].iPageNum=iTempPage[i];
			//缺页标记 
			flag[i]=1;
			// 将物理块中与引用串匹配的物理块的标记位置0,其余加1(模拟移位寄存器) 
			for(k=0;k<M;k++)
			   if(k!=loc)
			       myBlock[k].iBlockFlag++;
			    else
			       myBlock[k].iBlockFlag=0;
		}
		output(iTempPage[i],flag[i],myBlock,M);
	 } 
}

-------------------------------------------------------------------------------------------------

成果不易,如若有益,欢迎打赏

猜你喜欢

转载自blog.csdn.net/qq_39800695/article/details/84643612
今日推荐