rcu 机制简介 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/113999842一. RCU 基本概念

  • 读侧临界区 (read-side critical sections): RCU读者执行的区域,每一个临界区开始于rcu_read_lock(),结束于rcu_read_unlock(),可能包含rcu_dereference()等访问RCU保护的数据结构的函数。这些指针函数实现了依赖顺序加载的概念,称为memory_order_consume加载。
  • 写侧临界区:为适应读侧临界区,写侧推迟销毁并维护多个版本的数据结构,有大量的同步开销。此外,编写者必须使用某种同步机制(例如锁定)来提供有序的更新
  • 静默态(quiescent state): 当一个线程没有运行在读侧临界区时,其就处在静默状态。持续相当长一段时间的静默状态称之为延长的静默态(extended quiescent state)。
  • 宽限期(Grace period): 宽限期是指所有线程都至少A一次进入静默态的时间。宽限期前所有在读侧临界区的读者在宽限区后都会结束。不同的宽限期可能有部分或全部重叠。

读者在读临界区遍历RCU数据。如果写者从此数据中移除一个元素,需要等待一个宽限期后才能执行回收内存操作。上述操作的示意图如下图所示,其中,标有read的框框为一个读临界区。

上图中,每一个读者、更新者表示一个独立的线程,总共4个读线程,一个写线程。 RCU更新操作分为两个阶段:移除阶段回收阶段。两个阶段通过宽限期隔开。更新者在移除元素后,通过synchronize_rcu()原语,初始化一个宽限期,并等待宽限期结束后,回收移除的元素。 1. 移除阶段:RCU更新通过rcu_assign_pointer()等函数移除或插入元素。现代CPU的指针操作都是原子的, rcu_assign_pointer()原语在大多数系统上编译为一个简单的指针赋值操作。移除的元素仅可被移除阶段(以灰色显示)前的读者访问。 2. 回收阶段:一个宽限期后, 宽限期开始前的原有读者都完成读操作,因此,此阶段可安全释放由删除阶段删除的元素。

一个宽限期可以用于多个删除阶段,即可由多个更新程序执行更新。 此外,跟踪RCU宽限期的开销可能会均摊到现有流程调度上,因此开销较小。对于某些常见的工作负载,宽限期跟踪开销可以被多个RCU更新操作均摊,从而使每个RCU更新的平均开销接近零。

Listing E.2 并发的RCU删除

二. RCU 发布和订阅原语

三. RCU 三个基本组件

  1. Publish-Subscribe Mechanism (for insertion)
  2. Wait For Pre-Existing RCU Readers to Complete (for deletion)
  3. Maintain Multiple Versions of Recently Updated Objects (for readers)

这三个RCU组件使得数据可以在有并发读者时被改写,通过不同方式的组合,这三种组件可以实现各种基于RCU算法的变体。

1.Publish-Subscribe Mechanism

2.Wait For Pre-Existing RCU Readers to Complete

However, note that RCU read-side critical sections that begin after the beginning of a given grace period can and will extend beyond the end of that grace period.

The following pseudocode shows the basic form of algorithms that use RCU to wait for readers:

  1. Make a change, for example, replace an element in a linked list.
  2. Wait for all pre-existing RCU read-side critical sections to completely finish (for example, by using the synchronize_rcu() primitive). The key observation here is that subsequent RCU read-side critical sections have no way to gain a reference to the newly removed element.
  3. Clean up, for example, free the element that was replaced above.

展示上述三步流程的代码片段如下:

关于 synchronize_rcu()的进一步解释:

The synchronize_rcu() primitive might seem a bit mysterious at first. After all, it must wait for all RCU read-side critical sections to complete, and, as we saw earlier, the rcu_read_lock() and rcu_read_unlock() primitives that delimit RCU read-side critical sections don't even generate any code in non-CONFIG_PREEMPT kernels!

There is a trick, and the trick is that RCU Classic read-side critical sections delimited by rcu_read_lock() and rcu_read_unlock() are not permitted to block or sleep. Therefore, when a given CPU executes a context switch, we are guaranteed that any prior RCU read-side critical sections will have completed. This means that as soon as each CPU has executed at least one context switch, all prior RCU read-side critical sections are guaranteed to have completed, meaning that synchronize_rcu() can safely return.

Thus, RCU Classic's synchronize_rcu() can conceptually be as simple as the following:

  1 for_each_online_cpu(cpu)2   run_on(cpu);

Here, run_on() switches the current thread to the specified CPU, which forces a context switch on that CPU. The for_each_online_cpu() loop therefore forces a context switch on each CPU, thereby guaranteeing that all prior RCU read-side critical sections have completed, as required. Although this simple approach works for kernels in which preemption is disabled across RCU read-side critical sections, in other words, for non-CONFIG_PREEMPT and CONFIG_PREEMPT kernels, it does not work for CONFIG_PREEMPT_RT realtime (-rt) kernels. Therefore, realtime RCU uses a different approach based loosely on reference counters.

Of course, the actual implementation in the Linux kernel is much more complex, as it is required to handle interrupts, NMIs, CPU hotplug, and other hazards of production-capable kernels, but while also maintaining good performance and scalability. Realtime implementations of RCU must additionally help provide good realtime response, which rules out implementations (like the simple two-liner above) that rely on disabling preemption.

Although it is good to know that there is a simple conceptual implementation of synchronize_rcu(), other questions remain. For example, what exactly do RCU readers see when traversing a concurrently updated list? This question is addressed in the following section.

3.Maintain Multiple Versions of Recently Updated Objects

What is RCU, Fundamentally? [LWN.net]

开篇:RCU是什么?相关推荐

  1. linux内核rcu锁实例,Linux Rcu到底有没有锁?

    3.14内核代码 rcu机制不是宣称无锁吗? 但是rcu_lock_acquire那句是个锁吗?怎么解释呢?求解惑 806 static inline void rcu_read_lock(void) ...

  2. 一步步学敏捷开发:开篇

    一步步学敏捷开发:开篇 http://www.cnblogs.com/jetlian/p/3913687.html

  3. 【天命奇御】成就进度62/71的通关攻略(1·开篇前言)

    天命奇御于2018.8.9号在wegame上发售 先是一周目记录: 可以说一周目是熟悉最终boss技能后,靠技术过的...... 然后是二周目记录: 开篇前言: 转载于:https://www.cnb ...

  4. 开篇第一题:经典中的经典!

    开篇第一题:经典中的经典!                          --评<编程之美> 原贴地址:http://www.douban.com/review/2130819/ 应该 ...

  5. Silverlight实例教程 - Validation数据验证开篇

    Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...

  6. 精通Zookeeper系列开篇:进大厂不得不学的分布式协同利器!

    最近,有很多小伙伴让我更新一些Zookeeper的文章,正好也趁着清明假期把之前自己工作过程当中总结的Zookeeper知识点梳理了一番,打算写一个[精通Zookeeper系列],希望能够帮助小伙伴们 ...

  7. duilib 预开篇

    曾几何时,当我看到好看的windows 软件界面时,也想亲手写出这么绚丽好看的界面. 于是我就到处寻找windows UI编程教程.在一番查找和比较下,最终选择了duilib. 主要考虑到了duili ...

  8. Linux内核同步:RCU

    linux内核 RCU机制详解 简介 RCU(Read-Copy Update)是数据同步的一种方式,在当前的Linux内核中发挥着重要的作用.RCU主要针对的数据对象是链表,目的是提高遍历读取数据的 ...

  9. 创业公司如何做数据分析(一)开篇

    在过去的一年里,笔者加入了一家移动互联网创业公司,工作之一便是负责数据业务的建设,陆陆续续完成了一些数据系统的实现,来满足公司的数据需求.在创业公司中做数据相关的事情,而且是从零做起,肯定不像很多大公 ...

最新文章

  1. redis 主从复制的核心原理
  2. js等待 callback 执行完毕_前端开发,一篇文章让你彻底搞懂,什么是JavaScript执行机制!...
  3. 初识Kubernetes
  4. Java Hibernate 二级缓存配置及缓存的统计策略
  5. 深层学习:心智如何超越经验2.4 前景
  6. H.264的码率控制算法
  7. java8 lambda map排序_Android兼容Java 8语法特性的原理分析
  8. GDB 调试 Mysql 实战(一)源码编译安装
  9. sqlserver的for xml path和mysql的group_concat的区别
  10. UML/ROSE学习笔记系列二:UML的概念模型
  11. [Spring-cloud-eureka]使用 gradle, spring boot,Spring cloud Eureka 搭建服务提供者
  12. WeX5和BeX5的区别
  13. centos7 安装btsync
  14. 计算机上网记录怎么清除,电脑浏览器上网记录怎么删除
  15. STM32 ESP8266 无线模块使用
  16. H3CNE V7.0 视频教程
  17. 如何把microsoft store里面的软件添加到桌面
  18. AccessibilityService的学习,抢红包实现
  19. python网球比赛模拟主持稿_主持人大赛模拟主持环节情景
  20. HTC Vive VR操作规范书

热门文章

  1. Mapbox使用之sprite(图标符号)
  2. springboot整合freemarker案例
  3. 如何让新员工快速成长
  4. 常用电子元器件的一些特性(1)
  5. Kodi皮肤乱码改中文设置-Arctic: Zephyr- Reloaded
  6. mac配置flutter一条龙
  7. 软件造价评估(功能点计数元素ILF、EIF、IE、EO、EQ)
  8. 装配图中齿轮的画法_识读一级直齿圆柱齿轮减速器装配图
  9. 计算机专业课改理念,课改新理念
  10. 表格的一些常用样式以及属性