std::queue 单独无法判断命中,因其无 find() 成员函数且不提供迭代器接口,无法高效查询页是否在内存中;必须配合 std::unordered_set 同步维护驻留状态。

单独用 std::queue 模拟 FIFO 页面置换,命中率一定算错——它不维护驻留状态,查“页是否已在内存”只能遍历或根本不可行,淘汰后残留旧页号,导致重复缺页、命中虚低。
为什么 std::queue 单独无法判断命中
std::queue 没有 find() 成员函数,写 q.find(page) 直接编译失败;它也不提供迭代器接口,std::find(q.begin(), q.end(), page) 会编译报错。退而求其次把队列倒进 std::vector 再查?单次开销从 O(1) 变成 O(m),m=64 就要比较 64 次,还附带拷贝;更糟的是,队列里可能存着已被淘汰但没清理的页号,“假驻留”让连续访问(如 0 0 0)全判缺页。
必须同步维护 std::queue 和 std::unordered_set
二者职责严格分离:std::queue 管谁最老,std::unordered_set 管谁还在内存。所有增删操作必须原子对齐,漏一步就崩:
- 装入新页时:
pageQueue.push(page)✅ 且inMemory.insert(page)✅ - 淘汰旧页时:
int victim = pageQueue.front()→pageQueue.pop()✅ → 立即inMemory.erase(victim)✅ - 命中判断只查集合:
if (inMemory.find(page) != inMemory.end()),O(1),绝不碰pageQueue - 调用
pageQueue.front()前必须检查!pageQueue.empty(),尤其frameCount == 0或序列极短时
手写循环数组时 cur 指针的硬约束
用 std::vector<int> frames(frameCount, -1)</int> + int cur = 0 模拟,性能好但边界极易出错:
立即学习“C++免费学习笔记(深入)”;
-
cur初始值必须是0,不能是未定义值或-1(-1 % m在 C++ 中仍是负数,越界) -
cur只在发生缺页且inMemory.size() == frameCount时才更新:cur = (cur + 1) % frameCount - 数组大小必须严格等于
frameCount;多一分可能覆盖相邻变量,少一分会导致下标越界 - 首次装入阶段(内存未满)绝不能动
cur,否则最早装入的页会被跳过淘汰
命中率分母必须是总访问次数,一个都不能少
命中率 = (total_accesses - pageFaults) / total_accesses,这个 total_accesses 就是原始输入序列长度。常见错误包括:
- 把前
frameCount次“填空闲帧”的访问过滤掉再算分母 - 对访问序列去重后再统计
- 误用
pageFaults / frames.size()或其他非原始长度的值
哪怕序列是 7 0 1 2 0 3 共 6 次访问,分母就是 6;第 1 次访 7、第 2 次访 0 全算缺页,计入分子——真实 OS 的 pagefault 计数器就是从第一次访存开始累加的。


















