第 10 章 RCU 与 SRCU:宽限期驱动的无锁读
第 8 章的seqcount用序号与重试实现了无锁读但在小结里留了一个伏笔它只适用于读取值一旦读侧要顺着指针访问对象就得叠加 RCU——因为重试能保证读到的值前后一致却无法保证指针指向的对象在读的过程中没有被释放。本章补齐这块RCURead-Copy-Update正是专门解决对象生命周期的无锁读机制它让读者近乎零成本把全部代价搬到更新者一侧。RCU 的实现规模庞大本章只做综述锚定语义与关键接口深入的宽限期推进机制在 mmu-notifier 专栏 12.3 展开。本章源码为include/linux/rcupdate.h、kernel/rcu/tree.c与kernel/rcu/srcutree.c。说明以 x86-64、非PREEMPT_RT配置为主线。RCU 在不同抢占配置下读侧开销不同下文以经典可抢占语义描述。10.1 守护什么读者不设防更新者担全责RCU 的适用场景是读多写极少、且读侧要解引用指针的共享数据结构典型如链表、哈希表、路由表。它的核心约定是一组不对称的分工读者进入rcu_read_lock()到rcu_read_unlock()之间的读侧临界区其中可以放心解引用受 RCU 保护的指针全程不加锁、不自旋、不写任何共享状态。更新者采用“读—复制—更新”不原地修改而是复制一份、改好新副本、用一次指针发布切换过去随后等待一个宽限期确认所有可能看见旧对象的读者都已退出才释放旧对象。于是读侧几乎没有成本一致性完全由更新者通过“延迟释放”来保证——旧对象绝不会在还有读者引用时被回收。10.2 发布—订阅与宽限期RCU 的两根支柱都在屏障上。发布侧用rcu_assign_pointer订阅侧用rcu_dereference/* 发布smp_store_release确保对象初始化先于指针可见 */#definercu_assign_pointer(p,v)\smp_store_release(p,RCU_INITIALIZER((typeof(p))_r_a_p__v))/* 订阅READ_ONCE 依赖序读到指针后解引用不会被重排到前面 */prcu_dereference(gp);这对屏障保证读者要么看到旧对象、要么看到完整初始化后的新对象绝不会看到构造到一半的中间态。这正是第 8 章seqcount无法独立完成、必须叠加 RCU 的原因。另一根支柱是宽限期grace period。更新者摘除旧指针后用两种方式等待synchronize_rcu();/* 同步阻塞直到宽限期结束再返回 */call_rcu(obj-rcu,free_fn);/* 异步登记宽限期后由内核回调释放 */宽限期的定义是“所有在它开始前就已存在的读侧临界区都已结束”的一段时间。跨过它就再没有读者能引用旧对象回收才安全。等待策略在这里彻底移到了更新者身上读者零等待更新者用一段可能不短的延迟换取读侧的无锁。下图给出一次更新的完整时序新旧读者并发更新者发布新对象后等待宽限期待旧读者全部退出再释放旧对象。读者B 新更新者受保护指针读者A 旧读者B 新更新者受保护指针读者A 旧旧读者陆续 rcu_read_unlock所有旧读者已退出rcu_dereference 看到旧对象rcu_assign_pointer 发布新对象rcu_dereference 看到新对象synchronize_rcu 进入宽限期kfree 释放旧对象10.3 SRCU可睡眠的 RCU经典 RCU 的读侧临界区内不允许睡眠会拖住宽限期、乃至无法界定。当读侧确实需要阻塞——例如持读侧锁期间要做内存分配、等 I/O——就用 SRCUSleepable RCU。它把 RCU 按独立域切分每个域是一个struct srcu_struct域之间的宽限期互不牵连structsrcu_structsp;intidxsrcu_read_lock(sp);/* 返回一个 idx读侧可睡眠 *//* ...可阻塞的读侧临界区... */srcu_read_unlock(sp,idx);/* 必须回传同一个 idx */synchronize_srcu(sp);/* 更新者只等本域的读者 */与经典 RCU 相比有两处关键差异读侧srcu_read_lock返回一个idx且解锁时必须原样传回对应它内部翻转的一对 per-CPU 计数器宽限期按域计算一个域里的慢读者不会拖累其他域。代价是读侧比经典 RCU 略重要更新 per-CPU 计数。mmu-notifier 子系统正是用 SRCU 保护通知链——回调里可能睡眠这一场景在专栏 12.3 详述。10.4 与前几章的关系把 RCU 放回全书的坐标它与第 8 章seqcount是互补的两种无锁读。seqcount用序号重试保证读到的值自洽成本在读侧可能重试RCU 用宽限期保证指针指向的对象存活成本在更新侧等宽限期。读一个会被并发改写的标量快照用seqcount读一个会被并发替换、释放的对象用 RCU两者叠加才能安全地无锁遍历一个动态的指针结构。本章小结RCU 以极致不对称的分工实现无锁读读者在rcu_read_lock/rcu_read_unlock之间近乎零成本地解引用指针更新者用rcu_assign_pointer发布新对象、用宽限期synchronize_rcu或call_rcu延迟释放旧对象确保没有读者还在引用时才回收。SRCU 通过按域划分与可睡眠读侧覆盖读侧需要阻塞的场景代价是读侧略重。回到“锁 原子操作 屏障 等待策略”RCU 几乎放弃了读侧的原子操作只靠rcu_assign_pointer/rcu_dereference一对屏障维系可见性顺序而把等待策略整体挪到更新者的宽限期上。它补上了seqcount留下的“含指针须叠加 RCU”这一块两者合起来构成内核无锁读的完整图景。技术交流和投稿欢迎加入社区GPUers。

相关新闻

迁移到Apache Fesod:告别EasyExcel的复杂表头与嵌套List痛点

迁移到Apache Fesod:告别EasyExcel的复杂表头与嵌套List痛点

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 11:27:05 阅读更多 →
SpringBoot二手交易平台开发实战与架构设计

SpringBoot二手交易平台开发实战与架构设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 11:27:05 阅读更多 →
基于微信小程序的宠物定位追踪系统开发实践

基于微信小程序的宠物定位追踪系统开发实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/25 15:08:57 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/26 12:00:21 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/27 4:06:49 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/27 7:21:53 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/26 12:00:21 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/27 6:20:47 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/27 4:06:50 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 12:00:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 7:21:50 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 8:34:37 阅读更多 →