LRU最近最久未使用算法
2015-06-16 15:22 2082人阅读 评论(0) 收藏 举报
本文章已收录于:
分类:
C++(21)
操作系统学习(11)
版权声明:本文为博主原创文章,未经博主允许不得转载。
算法过程
最近最久未使用算法需要引入内存块时钟,即为每个内存块设定一个计时器,用于记录相应内存块中的页面已经存在的时间。每次置换选出所有内存块时钟中最大者作为被置换页面,当页面发生置换时,将其对应的计时器清零,并且其他计时器加1.可用等长的整型数组来表示每个内存块的计时器。
在内存块初始化后,取出页面访问序列队列的队头。首先判断内存块中是否已经存在该队头页面,如果存在则直接显示内存块当前情况;否则,判断此时内存是否已满。如果内存未满,循环遍历找出空闲内存块,进行页面置换;若内存已满,选出所有内存块时钟中最大者,并置换之,缺页数加1. 每发生一次置换,被置换页面内存所对应的计时器清零,其他计时器加1. 如此循环迭代,直到页面访问序列队列为空时,整个算法执行完毕。最后计算并显示缺页率。其流程图如图所示:
代码示例:
[cpp] view plain copy print?
- #ifndef PAGEREPLACEMENT_H
- #define PAGEREPLACEMENT_H
- #include <vector>
- class PageReplacement
- {
- public:
- PageReplacement();
- ~PageReplacement();
- void run();
- void LRU();
- private:
- void addInfo() const;
- private:
- int pages; // 虚拟内存的尺寸P
- int firstPageFramePos; // 工作面的起始位置p
- int pageFrames; // 工作面中包含的页数e
- int rateM; // 工作面移动率m
- std::vector<int> seqVec; // 序列号
- std::vector<int> mem; // 内存块
- };
- #endif // PAGEREPLACEMENT_H
#ifndef PAGEREPLACEMENT_H
#define PAGEREPLACEMENT_H
#include <vector>
class PageReplacement
{
public:
PageReplacement();
~PageReplacement();
void run();
void LRU();
private:
void addInfo() const;
private:
int pages; // 虚拟内存的尺寸P
int firstPageFramePos; // 工作面的起始位置p
int pageFrames; // 工作面中包含的页数e
int rateM; // 工作面移动率m
std::vector<int> seqVec; // 序列号
std::vector<int> mem; // 内存块
};
#endif // PAGEREPLACEMENT_H
[cpp] view plain copy print?
- #include "PageReplacement.h"
- #include <iostream>
- #include <cstdlib>
- #include <list>
- PageReplacement::PageReplacement()
- : mem(3, -1)
- {
- this->run();
- }
- PageReplacement::~PageReplacement()
- {
- }
- void PageReplacement::run()
- {
- std::cout << "请输入虚拟内存尺寸P:";
- std::cin >> pages;
- std::cout << "请输入工作面的起始位置p:";
- std::cin >> firstPageFramePos;
- std::cout << "请输入工作面中包含的页数e:";
- std::cin >> pageFrames;
- std::cout << "请输入工作面移动率m:";
- std::cin >> rateM;
- std::cout << "请输入在0和1之间的值t:";
- std::cin >> t;
- for (int i = 0; i < rateM; ++i)
- {
- int randomNum = (rand() % pageFrames) + firstPageFramePos;
- seqVec.push_back(randomNum);
- }
- std::cout << "序列号:";
- for (int i = 0; i < seqVec.size(); ++i)
- {
- std::cout << seqVec.at(i) << " ";
- }
- std::cout << std::endl;
- }
- void PageReplacement::LRU()
- {
- int nLack = 0; // 缺页数
- std::list<int> seqList(seqVec.begin(), seqVec.end());
- int nTotal = seqList.size();
- std::vector<int> timer(mem.size(), 0); // 每个内存块对应的时钟
- while (!seqList.empty())
- {
- int head = *seqList.begin(); // 去队头的页面
- seqList.pop_front();
- bool equal = false; // 标识内存中是否有与队头相等的页面
- int vacant = -1; // 标识内存中是否有空闲页面
- for (int i = 0; i < mem.size(); ++i)
- {
- if (mem.at(i) == head) // 如果找到相等的页面
- {
- equal = true;
- this->addInfo(); // 显示内存块
- timer.at(i) = -1; // 相等的时钟清零,其他的时钟加1
- for (int j = 0; j < timer.size(); ++j)
- {
- ++timer[j];
- }
- break;
- }
- else if (mem.at(i) == -1 && vacant == -1) // 如果找到空闲位
- {
- vacant = i;
- }
- }
- if (equal) // 如果找到相等的页面,则进行下一个查找
- {
- continue;
- }
- ++nLack;
- if (vacant != -1)
- {
- mem[vacant] = head; // 把队头的放入到空闲位中
- this->addInfo();
- timer[vacant] = -1; // 空闲位时钟清零,其他时钟加1
- for (int j = 0; j < timer.size(); ++j)
- {
- ++timer[j];
- }
- continue;
- }
- else
- {
- int max = timer[0];
- int subIndex = 0;
- for (int p = 0; p < timer.size(); ++p)
- {
- if (timer.at(p) > max)
- {
- max = timer.at(p); // 找到最近最久没有被使用的内存块
- subIndex = p;
- }
- }
- mem[subIndex] = head; // 把队头的放入到最近最久未被使用的内存块中
- this->addInfo();
- timer[subIndex] = -1;
- for (int j = 0; j < timer.size(); ++j)
- {
- ++timer[j];
- }
- }
- }
- std::cout << "缺页率: " << (double)nLack/nTotal * 100 << "%" << std::endl;
- }
- void PageReplacement::addInfo() const
- {
- std::cout << mem.at(0) << " " << mem.at(1) << " " << mem.at(2) << std::endl;
- }
#include "PageReplacement.h"
#include <iostream>
#include <cstdlib>
#include <list>
PageReplacement::PageReplacement()
: mem(3, -1)
{
this->run();
}
PageReplacement::~PageReplacement()
{
}
void PageReplacement::run()
{
std::cout << "请输入虚拟内存尺寸P:";
std::cin >> pages;
std::cout << "请输入工作面的起始位置p:";
std::cin >> firstPageFramePos;
std::cout << "请输入工作面中包含的页数e:";
std::cin >> pageFrames;
std::cout << "请输入工作面移动率m:";
std::cin >> rateM;
std::cout << "请输入在0和1之间的值t:";
std::cin >> t;
for (int i = 0; i < rateM; ++i)
{
int randomNum = (rand() % pageFrames) + firstPageFramePos;
seqVec.push_back(randomNum);
}
std::cout << "序列号:";
for (int i = 0; i < seqVec.size(); ++i)
{
std::cout << seqVec.at(i) << " ";
}
std::cout << std::endl;
}
void PageReplacement::LRU()
{
int nLack = 0; // 缺页数
std::list<int> seqList(seqVec.begin(), seqVec.end());
int nTotal = seqList.size();
std::vector<int> timer(mem.size(), 0); // 每个内存块对应的时钟
while (!seqList.empty())
{
int head = *seqList.begin(); // 去队头的页面
seqList.pop_front();
bool equal = false; // 标识内存中是否有与队头相等的页面
int vacant = -1; // 标识内存中是否有空闲页面
for (int i = 0; i < mem.size(); ++i)
{
if (mem.at(i) == head) // 如果找到相等的页面
{
equal = true;
this->addInfo(); // 显示内存块
timer.at(i) = -1; // 相等的时钟清零,其他的时钟加1
for (int j = 0; j < timer.size(); ++j)
{
++timer[j];
}
break;
}
else if (mem.at(i) == -1 && vacant == -1) // 如果找到空闲位
{
vacant = i;
}
}
if (equal) // 如果找到相等的页面,则进行下一个查找
{
continue;
}
++nLack;
if (vacant != -1)
{
mem[vacant] = head; // 把队头的放入到空闲位中
this->addInfo();
timer[vacant] = -1; // 空闲位时钟清零,其他时钟加1
for (int j = 0; j < timer.size(); ++j)
{
++timer[j];
}
continue;
}
else
{
int max = timer[0];
int subIndex = 0;
for (int p = 0; p < timer.size(); ++p)
{
if (timer.at(p) > max)
{
max = timer.at(p); // 找到最近最久没有被使用的内存块
subIndex = p;
}
}
mem[subIndex] = head; // 把队头的放入到最近最久未被使用的内存块中
this->addInfo();
timer[subIndex] = -1;
for (int j = 0; j < timer.size(); ++j)
{
++timer[j];
}
}
}
std::cout << "缺页率: " << (double)nLack/nTotal * 100 << "%" << std::endl;
}
void PageReplacement::addInfo() const
{
std::cout << mem.at(0) << " " << mem.at(1) << " " << mem.at(2) << std::endl;
}
[cpp] view plain copy print?
- #include <iostream>
- #include "PageReplacement.h"
- int main()
- {
- PageReplacement pageReplacement;
- pageReplacement.LRU();
- return 0;
- }
#include <iostream>
#include "PageReplacement.h"
int main()
{
PageReplacement pageReplacement;
pageReplacement.LRU();
return 0;
}
顶
0
踩
0
- 上一篇FIFO先进先出置换算法
- 下一篇简单Clock算法
我的同类文章
C++(21) 操作系统学习(11)
- •Pthread 互斥2015-08-11阅读286
- •POSIX 线程小结2015-08-11阅读283
- •线程模式2015-08-09阅读489
- •I/O多路复用之总结2015-08-08阅读412
- •I/O 多路复用之select2015-08-08阅读410
- •改进型Clock算法2015-06-16阅读1074
- •POSIX 线程小结(续)2015-08-11阅读252
- •线程模型2015-08-09阅读368
- •线程小结2015-08-09阅读262
- •I/O 多路复用之poll2015-08-08阅读304
- •分散/聚集 I/O(scatter-gather I/O)2015-08-06阅读860