std::queue 单独无法判断命中,因其无 find() 成员函数且不支持迭代器,无法 O(1) 查询页是否在内存中,强行遍历导致性能退化和逻辑错误。

单独用 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 模拟 FIFO,性能好但极易越界或逻辑漂移:
立即学习“C++免费学习笔记(深入)”;
-
cur初始值必须是0,不能是未定义值或-1(-1 % m在 C++ 中仍是负数,越界) -
cur只在发生缺页且inMemory.size() == frameCount时才更新:cur = (cur + 1) % frameCount - 数组大小必须严格等于
frameCount;多一分可能覆盖相邻变量,少一分会导致cur越界写入 - 首次装入阶段(内存未满)绝不能动
cur,否则最早装入的页会被跳过淘汰
命中率分母必须是总访问次数,一个都不能少
命中率 = (total_accesses - pageFaults) / total_accesses,这个 total_accesses 就是原始输入序列长度,不是装入次数、不是去重后长度、更不是“填满内存后的访问数”。常见错误是把前 frameCount 次“填空闲帧”的访问过滤掉,结果分子分母同时偏移,命中率失真且不可比。哪怕序列是 7 0 1 2 0 3 共 6 次访问,分母就是 6;第 1 次访 7、第 2 次访 0 全算缺页,计入分子——真实 OS 的 pagefault 计数器就是从第一次访存开始累加的。


















