seqcount / seqlock 与顺序计数同步

这页讲的是:有些共享数据读得非常频繁,大家不想让所有读者都老老实实排队,但又必须知道自己有没有读到写入中的不完整快照。学这页的重点,是理解 seqcount / seqlock 的思路不是“绝不重读”,而是“让读者先快读,若撞上写者就认错重来”。

这块是什么

seqcount / seqlock 与顺序计数同步,讲的是 Linux 怎样在一些读非常频繁、写相对较少的共享数据场景下,让读者先不和彼此互斥,而是通过顺序计数判断“这次读到的是不是稳定版本”。它关注的是“读者快速尝试,若不稳定就重试”,而不是让所有读者都无条件排队等待。

可以把它理解成:你在抄一块公告板内容,如果管理员正在改板子,你可能会抄到一半发现前后对不上。这时不是强迫所有人排队,而是让你确认版本不一致就重抄一遍。

它负责什么

让读者先快速读取

  • 如果每个读者都去抢重锁,读路径代价可能太高
  • 顺序计数允许读者先快速拿一份快照
  • 把常见的“无人写入”情况走得更轻
  • 让读多场景少一点排队感

在写入干扰时要求重试

  • 写者修改期间,读者可能拿到不一致片段
  • 顺序计数帮助读者识别这次读是否可靠
  • 如果撞上写入,就放弃本次结果重来
  • 让“快读”不以错误快照为代价

把读写不对称进一步压榨出来

  • 有些场景甚至不想让读者拿共享锁
  • 只要读者愿意偶尔重试,就能换来更轻的读路径
  • 让无写入时的读取非常顺滑
  • 把少量重试成本换成高频读扩展性

为什么它不是“万能无锁读取”

如果想得太简单会怎样真正关键在哪
觉得读者既然不排队就一定最好会忽略一旦写入变多,重试成本可能明显上升。它最适合写少且每次重读代价可接受的场景。
把它当完全无条件一致快照会漏掉读者其实承担了“发现不稳就重来”的责任。正确性依赖重试协议,而不是一次读必然成功。
觉得它能替代所有读写锁会忽略并不是所有对象都适合反复重读或容忍中途失败。对象形态和读写模式必须匹配这种设计。
不把顺序和可见性当回事会让读者误把半更新状态当完整结果。这类机制本质上强依赖正确的顺序语义。

关键概念

概念现在怎么理解
seqcount用顺序计数告诉读者:这次读前后的版本号是否稳定一致。
seqlock在顺序计数思想上,再明确写者更新时的独占修改路径。
重试读者发现自己撞上写入,就放弃本次结果重新读。
稳定快照读者前后看到的版本一致,说明读到的是同一轮稳定状态。
写少读多这类同步最适合大量读取、少量更新的对象形态。

为什么重要

常见误解

它不负责什么

和其他模块的关系

相关模块关系
rwsem都偏向读多写少,但 rwsem 让读者正式持锁,seqcount / seqlock 更强调读者快速尝试加重试。
memory barriers读者能不能正确判断一轮写入是否完整,离不开正确的顺序和可见性保证。
RCU两者都在减轻读路径负担,但一个靠重试快照,一个更偏向延后回收和轻读访问。
时间与状态快照很多只想快速读取当前状态、又能接受偶尔重试的场景都容易考虑这类机制。

读完这页后,你应该能回答

后面适合继续问:什么时候快照类数据更适合 seqcount,而不是 rwsem?读者重试在高写入压力下会出现什么体感问题?seqlock 和 RCU 最容易被混在哪一层?