操作系统页面置换算法

最近写了一下操作系统页面置换的几个算法,给大家分享一下:

#define  P       5000            //定义虚拟内存页面总数

#define  SUM      200000             //定义要产生的随机数的总数定义的结构体:

typedef struct page

{

       int pagenumber;                //定义页号

       int time;                      //定义调入的时间,不调用时time+1

       int visit;                     //访问位,clock算法

       int count;        //记录OPT算法识别下一个相同数据的访问步长

}Page;

FIFO,LRU,CLOCK,随机替换,最佳算法的主要算法如下:

FIFO算法:

if(某页面不存在于内存)

{

缺页数++;

If(内存满了)

{

获取存在时间最大的位置,并替换该数据;

该位置时间置零;

}

否则加载到最后一个位置;

}

将所以未被替换的数据时间+1;

LRU算法:

if(某页面不存在于内存)

{

缺页数++;

If(内存满了)

{

内存数据左移;将新数据添加到最后一个位置;

}

否则加载到最后一个位置;

}

else

{

找到该数据位置,并将之后的数据左移,将该数据放到最后一个位置;

}

CLOCK算法:

if(某页面不存在于内存)

{

缺页数++;

If(内存不满)

{

将数据放在内存的最后一个位置;

}

else{

替换第一visit=0的页面;

}

}

else

{

否则将页面的访问位置1

}

 

OPT(最佳)算法:

if(某页面不存在于内存)

{

缺页数++;

If(内存不满)

{

将数据放在内存的最后一个位置;

}

else{

找到最长不使用的页面的位置;

替换该位置的数据;

}

}

求以后永不使用的,或者是在最长时间内不再被访问的页面算法:

for(页面所有数据)

{

for(从当前RS[i]的位置开始到最后的数据)

{

if(数据存在页面中)

{

返回;

}

else{

页面计数值+1;

}

}

if(RS之后的数据中不存在某数据)

返回内存中该数据的位置;

}

求得最大的count值的数据的位置并返回;

随机替换算法:

if(某页面不存在于内存)

{

缺页数++;

if(内存不满)

{

将数据放在内存的最后一个位置;

}

else{

随机找一个位置替换;

}

}

void FIFOAlgorithm(int leaf)
{
	int temp;//临时变量
	static int total=0;//计算RS[]中第?个值
	total++;
	if(isInMemory(leaf)==P)//不存在页面中
	{
		lose_page_counter++;
		if(isFull() == -1)//如果满了
		{//置换
			temp = getMaxTimePos();
			pageUnit[temp].pagenumber = leaf;
			pageUnit[temp].time = 0;
		//	pageUnit[temp].visit++;//
		//	printf("%d,%d\n",total,leaf);//输出新数据RS[]位置和数据值
		}//if
		else
		{
			pageUnit[isFull()].pagenumber=leaf;
		//	printf("前期:%d\n",leaf);
		}
	}//if
//	printf("\n");
	for(int i=0;i<P;i++)
	{
	//	printf("%d\t",pageUnit[i].pagenumber);
		if(pageUnit[i].pagenumber!=-1)//该位置存在数据
		{
			pageUnit[i].time++;//页面内存在的项存在时间递增
		}
	}//for
}
void LRUAlgorithm(int leaf)
{
	if(isInMemory(leaf)==P)//不存在页面中
	{
		lose_page_counter++;

		if(isFull() == -1)//如果满了
		{//置换
			for(int i=0;i<P;i++)//将所有左移,最后一个数据加入
				pageUnit[i].pagenumber=pageUnit[1+i].pagenumber;
			pageUnit[P].pagenumber=leaf;//将数据放入最后一个页面中
		}//if
		else
		{
			pageUnit[isFull()].pagenumber=leaf;
		}//else
	}//if
	else         //存在页面中
	{
		int j=isInMemory(leaf);//记录leaf在页面的位置
		if(j == P-1 )//如果正好是页面最后一个
		{
			return ;//
		}//if
		else
		{
			int last = isInMemory(-1) ; //求最后一个数的位置
			for(j;j<last-1;j++)
			{
				pageUnit[j].pagenumber=pageUnit[1+j].pagenumber;
			}//for
			pageUnit[j].pagenumber=leaf;
		}//else
	}
}//end 
void OPTAlgorithm(int leaf)
{
	//int pos;
	if(isInMemory(leaf)==P)//如果页面号不在内存中
	{
		lose_page_counter++;       //缺页数+1
		int full =isFull();
		if(full != -1)//如果缓冲区P不满,加载
		{
			pageUnit[full].pagenumber=leaf;
		}//if
		else//如果缓冲区满了,置换
		{
			pageUnit[getLongestTimePage(location)].pagenumber = leaf;
			//置换结束后重新将count计数器初始化
			for(int i = 0;i<P;i++)
			{
				pageUnit[i].count=0;
			}
		}//else
	}//if
	location++;//求RS执行的位置
}
void RArqDAlgorithm(int leaf)
{
	//在页面内不做处理。。。

	if(isInMemory(leaf)==P)//如果页面号不在内存中
	{
		lose_page_counter++;       //缺页数+1
		int full =isFull();
		if(full != -1)//如果缓冲区P不满,添加
		{
			pageUnit[full].pagenumber=leaf;
		}//if
		else//如果缓冲区满了,随机替换一个值
		{
			static int random =0;
			random=rand()%20;
			pageUnit[random].pagenumber = leaf;
		}//else
	}//if
}
void ClockAlgorithm(int leaf)
{
	if(isInMemory(leaf)==P)//如果页面号不在内存中
	{
		lose_page_counter++;       //缺页数+1
		int full =isFull();
		if(full != -1)//如果缓冲区P不满,加载
		{
			pageUnit[full].pagenumber=leaf;
			pageUnit[full].visit=1;//其访问位置1
		}//if
		else//如果缓冲区满了,替换visit=0的第一个值
		{
			for(int i=point;i<P+point;i++)//从point指针开始
			{
				if(pageUnit[i%P].visit==0)
				{
					pageUnit[i%P].pagenumber=leaf;
					pageUnit[i%P].visit=1;
					point = (i+1)%P;     //指针下移
					break;             //跳出for循环
				}
				else
				{
					pageUnit[i%P].visit=0;//将访问位更改为0
				}
			}//for
		}//else
	}//if
	else            //页面号在内存中,符合的值置为1,指针不变
	{
		pageUnit[isInMemory(leaf)].visit=1;
	}//else
}//end ClockAlgorithm
int getLongestTimePage(int location)
{
	static int len = getLength(RS);
	int position=0;          //要替换的数据的位置 0<=position<P
//	static int location = 0;  //记录指针走到的位置
	for(int i=0;i<P;i++)
	{
		for(int j=location;j<len;j++)
		{
			if(pageUnit[i].pagenumber==RS[j])
			{
				break;        //找到了就退出
			}
			else
			{
				pageUnit[i].count++;          //计算查询到相同的数据所需要的步长
			}
		}
		if(pageUnit[i].count+location>=len)//如果在以后的数据中没有这个pageUnit[i].pagenumber,直接替换即可
		{
			position = i;
			return position;//直接返回这个位置,可以置换这个数据
		}
	}
	//查询最长的数据,求pageUnit[i].count的最大值 
	int step_ = 0; 
	for(i=0;i<P;i++)
	{
		if(pageUnit[i].count >= pageUnit[step_].count)
		{
			step_ = i;                //step_保存最大值对应的i值
			pageUnit[step_].count = pageUnit[i].count; //pageUnit[step_].count保存最大的值
		}
		
	}
	position = step_;  //将最大的值返回position
	return position;
}
int getMaxTimePos()
{
	int max = 0;                           //max记录存在时间的最大值
	for(int i=0;i<P;i++)
	{
		if(pageUnit[i].time > max)
		{
			max = pageUnit[i].time;         //max更新
			position = i;                   //更新 position 值
		}
	}
	return position;
}
/*
*   检查某页面是否在内存中
*   return 页面的位置
*/
int isInMemory(int leaf)
{
	for(int i=0;i<P;i++)
	{
		if(pageUnit[i].pagenumber == leaf)
			return i;                      //在页面内
	}
	return P;                             //不在页面内
}

/*
*  判断内存是否满了
*  无输入
*/
int isFull()
{
	for(int i = 0;i<P;i++)
	{
		if(pageUnit[i].pagenumber == -1 )
			return i;                    //内存不满
	}
	return -1;                             //内存满了
}

int getLength(int Array[])
{
	int i=0;
	while(Array[i] != '\0'  && i<SUM)
		i++;
	return i;
}


其它的RS串可以自己添加或者利用如下算法自己生成:

1. 确定虚拟内存的尺寸P,工作面的起始位置p,工作面中包含的页数e,工作面移动率m,以及一个范围在0 1 之间的值t

2. 生成m 个取值范围在p p + e 间的随机数,并记录到引用串中

3. 生成一个随机数r[0,r]

4. 如果r < t,则为p 生成一个新值,否则p = (p + 1)modP

5. 如果想继续加大引用串的长度,请返回第而2 步,否则结束

执行如下:

 int length=getLength(RS);
    lose_page_counter=0;
 for(int i=0;i<length;i++)
 {
  FIFOAlgorithm(RS[i]);
 }

输出lose_page_counter即为缺页数,而lose_page_counter/length即该算法的缺页率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值