FIFO页面置换仅用std::queue会出错,因其不维护驻留状态,导致缺页判断失效、命中率虚高;必须配合unordered_set同步增删页号,并严格按时间顺序更新队列与集合。

FIFO 页面置换不能只靠 std::queue 就跑通——缺页判断失效、命中率虚高、淘汰错位,八成是因为漏掉了驻留状态同步和 cur 更新边界。
为什么 std::queue 单独用会算错命中率
因为 std::queue 只管进出顺序,不存“当前哪些页在内存里”。每次访问前必须 O(1) 判断页号是否已驻留,否则就会把本该命中的页当成缺页重新装入。
- 仅用
std::queue+std::vector存内容 → 查驻留要遍历整个队列,m=64时单次判断就是 64 次比较 - 用了
std::unordered_set但没在装入/淘汰时同步增删 → 集合里残留旧页号,后续访问被误判为缺页 - 淘汰页后只弹出
queue,忘了从unordered_set中erase()→ 同一页第二次访问仍被当缺页
cur 指针在循环数组里怎么不出界
手写 FIFO 常用 int frames[64] + int cur 模拟队头,靠 cur = (cur + 1) % m 移动。但这个取模只在 m > 1 时安全;m == 1 时 (cur + 1) % 1 恒为 0,逻辑没错,但容易掩盖初始化漏洞。
- 数组必须严格按物理块数
m分配,new int[m]或std::array,不能多一分少一寸 -
cur初始值必须是0,且所有读写都用frames[cur % m],不能直接用frames[cur] - 只在发生缺页且内存已满时才更新
cur;命中时不挪动,否则“最老页”定义就乱了
命中率分母为什么必须是总访问次数
缺页率 = 缺页次数 / 总访问次数,分母就是输入页面序列长度 n,不是装入页数、不是去重页数、也不是“填满后”的访问数。
- 示例序列
7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1共 17 个访问 → 分母固定为 17 - 第 1 次访问页 7:缺页,计入分子;第 5 次再访问页 0:命中,不计分子但计入分母
- 若跳过前
m次(填空阶段)不计分母 → 命中率会被人为拉高,和真实 OS 行为脱节
最容易被忽略的是:FIFO 的“先进”指页进入内存的时间戳,不是它在访问序列里的下标。交叉访问(如 0 1 2 0 1 3)下,仅靠队列头尾无法反映谁更老——必须确保每次装入都追加到逻辑尾部、淘汰只从逻辑头部取,且驻留集合与队列内容时刻一致。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











