该记录着重介绍下:2.6.34版本中非抢占式RCU的基本概念。

RCU保护的是指针,因为指针的赋值可以使用原子操作完成;

在非抢占式RCU中:

对于读者,RCU仅需要抢占失效,因此获得读锁和释放读锁分别定义为:
对于非抢占式RCU,在操作读取数据的过程中不允许进程切换,否则因为写者需要等待读者完成,写者进程也会一直被阻塞。
#define rcu_read_lock() preempt_disable()
#define rcu_read_unlock() preeempt_enable() 变种:
#define rcu_read_lock_bh() local_bh_disable()
#define rcut_read_unlock_bh() local_bh_enable()
每个变种只在修改是通过call_rcu_bh进行的情况下使用,因为call_rcu_bh将把softirq的执行完毕也认为是一个quiescent state,因此如果修改是通过call_rcu_bh进行的,在进程上下文的读段临界区必须使用这一变种)。 rcu_dereference(p)相当于p
rc_assign_pointer(p, v)相当于p = v; 注意,关于写者:
写者在访问被RCU保护的共享数据时不需要和读者竞争任何锁,只有在有多于一个写者的情况下需要获得某种锁以与其它写者同步。
写者修改数据前先拷贝一个被修改元素的副本,然后在副本上进行修改,修改完毕后将向垃圾回收器注册一个回调函数以便在适当的时机执行真正的修改操作。                                                                                         

如何判断当前的一个读者已经完成了相应的读操作?

grace period 与 quiescent state的定义:

grace period(宽限期):
The time waits for any currently executing RCU read-side critical sections to complete, and the length of this wait is known as a "grace period". quiescent state(静默状态):
CPU发生了上下文切换称为经历一次quiescent state grace period就是所有CPU都经历一次quiescent state所需要的等待时间。因为对于非抢占式RCU机制而言,当所有CPU都经过quiescent state就意味着所有读者完成了对共享临界区的访问。 垃圾收集器在grace period之后调用写者注册的回调函数来完成真正的数据释放、唤醒线程等操作。

下图,引述自:http://blog.csdn.net/junguo/article/details/8244530

对图中的remove(删除)与reclamation(销毁),RCU作者本人做了解释:

The basic idea behind RCU is to split updates into "removal" and "reclamation" phases. The removal phase removes references to data items within a data structure (possibly by replacing them with references to new versions of these data items), and can run concurrently with readers. The reason that it is safe to run the removal phase concurrently with readers is the semantics of modern CPUs guarantee that readers will see either the old or the new version of the data structure rather than a partially updated reference. The reclamation phase does the work of reclaiming (e.g., freeing) the data items removed from the data structure during the removal phase. Because reclaiming data items can disrupt any readers concurrently referencing those data items, the reclamation phase must not start until readers no longer hold references to those data items.

Splitting the update into removal and reclamation phases permits the updater to perform the removal phase immediately, and to defer the reclamation phase until all readers active during the removal phase have completed, either by blocking until they finish or by registering a callback that is invoked after they finish. Only readers that are active during the removal phase need be considered, because any reader starting after the removal phase will be unable to gain a reference to the removed data items, and therefore cannot be disrupted by the reclamation phase.

So the typical RCU update sequence goes something like the following:

a、Remove pointers to a data structure, so that subsequent readers cannot gain a reference to it.
b、Wait for all previous readers to complete their RCU read-side critical sections.
c、At this point, there cannot be any readers who hold references to the data structure, so it now may safely be reclaimed (e.g., kfree()d).

非抢占式RCU的优缺点,以及引入RCU机制给优先级带来的问题:

引述自:http://lwn.net/Articles/263130/

Advantages of RCU include performance, deadlock immunity, and realtime latency. 
There are, of course, limitations to RCU, including the fact that readers and updaters run concurrently, that low-priority RCU readers can block high-priority threads waiting for a grace period to elapse, and that grace-period latencies can extend for many milliseconds.

RCU与seqlock的不同:

Although seqlock readers can run concurrently with seqlock writers, whenever this happens, the read_seqretry() primitive will force the reader to retry. This means that any work done by a seqlock reader running concurrently with a seqlock updater will be discarded and redone. So seqlock readers can run concurrently with updaters, but they cannot actually get any work done in this case. 

RCU类似于“强引用计数机制”

Because grace periods are not allowed to complete while there is an RCU read-side critical section in progress, the RCU read-side primitives may be used as a restricted reference-counting mechanism.
The effect is that if any RCU-protected data element is accessed within an RCU read-side critical section, that data element is guaranteed to remain in existence for the duration of that RCU read-side critical section.

RCU机制不是简单的等待事件完成

One of RCU's great strengths is that it allows you to wait for each of thousands of different things to finish without having to explicitly track each and every one of them, and without having to worry about the performance degradation, scalability limitations, complex deadlock scenarios, and memory-leak hazards that are inherent in schemes that use explicit tracking.

非抢占式RCU中的一些概念的更多相关文章

  1. 非抢占式RCU中关于grace period的处理(限于方法)

    参考自:http://blog.csdn.net/junguo/article/details/8244530             Documentation/RCU/* TREE_RCU将所有的 ...

  2. 非抢占式RCU实现(一)

    关于RCU的实现,考虑如下情形: 1.非抢占式RCU 2.限于嵌入式系统4核.每核单线程 3.RCU_FANOUT = 32 此时,RCU_TREE退化为单节点,如下,针对rcu_sched_stat ...

  3. 抢占式内核与非抢占式内核中的自旋锁(spinlock)的差别

    一.概括 (1)自旋锁适用于SMP系统,UP系统用spinlock是作死. (2)保护模式下禁止内核抢占的方法:1.运行终端服务例程时2.运行软中断和tasklet时3.设置本地CPU计数器preem ...

  4. 非抢占式RCU实现(二),解释:为什么 RCU_NEXT_SIZE 宏值是4?

    参考:2.6.34 一个很奇怪的问题. 没有查找到为什么 RCU_NEXT_SIZE的值为4的原因(包括Documentation),主要是在rcu_state中定义了一个四级的list,感到很有意思 ...

  5. chapter9_4 非抢占式的多线程

    协同程序与常规的多线程不同之处:协同程序是非抢占式的. 当一个协同程序运行时,是无法从外部停止它的.只有当协同程序显式地调用yield时,它才会停止. 当不存在抢先时,编程会变得简单很多,无须为同步的 ...

  6. 一种基于C51单片机的非抢占式的操作系统架构

    摘 要:从Keil C51的内存空间管理方式入手,着重讨论实时操作系统在任务调度时的重入问题,分析一些解决重入的基本方式与方法:分析实时操作系统任务调度的占先性,提出非占先的任务调度是能更适合于Kei ...

  7. keepalived的抢占与非抢占模式

    目录 一:keepalived的抢占与非抢占模式 1.抢占模式 2.非抢占模式 二:接下来分4种情况说明 三:以上3种,只要级别高就会获取master,与state状态是无关的 一:keepalive ...

  8. socket网络编程中的同步,异步,阻塞式,非阻塞式,有何联系与区别?

    一.举个打电话的例子: 阻塞   block   是指,你拨通某人的电话,但是此人不在,于是你拿着电话等他回来,其间不能再用电话.同步大概和阻塞差不多. 非阻塞   nonblock   是指,你拨通 ...

  9. MVC的验证(模型注解和非侵入式脚本的结合使用) .Net中初探Redis .net通过代码发送邮件 Log4net (Log for .net) 使用GDI技术创建ASP.NET验证码 Razor模板引擎 (RazorEngine) .Net程序员应该掌握的正则表达式

    MVC的验证(模型注解和非侵入式脚本的结合使用)   @HtmlHrlper方式创建的标签,会自动生成一些属性,其中一些属性就是关于验证 如图示例: 模型注解 通过模型注解后,MVC的验证,包括前台客 ...

随机推荐

  1. wcf中的Message类

    客户端->服务端—>客户端 客户端代码: using (new OperationContextScope(client.InnerChannel))            {       ...

  2. docker探索-docker容器基本操作(五)

    1.创建一个容器并启动 1.1.docker hello word Docker 允许你在容器内运行应用程序, 使用 docker run 命令来在容器内运行一个应用程序. 输出Hello world ...

  3. thinkphp前台模版字符串截取

    ThinkPHP\Common\extend.php 中管理前台模版的截取{$vons.title|msubstr=0,26} 原始的代码是无法使用截取支持…. 由于涉及到只有汉字检测最为准确 需要加 ...

  4. redis AOF 和RDB

    AOF定义:以日志的形式记录每个操作,将Redis执行过的所有指令全部记录下来(读操作不记录),只许追加文件但不可以修改文件,Redis启动时会读取AOF配置文件重构数据 换句话说,就是Redis重启 ...

  5. 火狐FireFox57不支持Tab Mix Plus插件的问题

    火狐的Tab Mix Plus插件管理标签页很好用,但是在这次升级到57版本后不能用了,也没找到合适的替代品. 该插件一个很常用的功能是在新建的标签页打开网页(而不是在当前页上跳转),该功能直接修改C ...

  6. win10用filezilla server搭建ftp服务器一直无法访问

    win10用filezilla server搭建ftp服务器一直无法访问?? 是防火墙导致的,防火墙中允许filezilla server程序的

  7. Knockout开发中文API系列4–监控属性数组

    PS:这个翻译系列好久都没有更新了,实在是不应该,一方面是由于时间不多,另一方面也由于自身惰性太大,从今天起接着更新,会在最近的一月内把这个系列中文API文档翻译完整. 如果你想侦测并响应一个对象的变 ...

  8. sql分页存储过程比较

    一,先创建一百万条数据 drop table #tmp create table #tmp ( id ,) primary key, name ) ) declare @i int begin ins ...

  9. 【嵌入式】——ads1.2的安装注意事项

    安装完ads的时候会出现错误,因为还要安装License Installation Wizard. 下一步会出现这个 然后点击Browse... 找到ads1.2下的CRACK(crack)文件夹的L ...

  10. 百度地图Api进阶教程-创建标注和自定义标注3.html

    <!DOCTYPE html> <html> <head> <meta name="viewport" content="ini ...