最近写了一下操作系统页面置换的几个算法,给大家分享一下:
#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即该算法的缺页率。