一:前言 RCU 机制出现的比较早,只是在 linux kernel 中一直到 2.5 版本的时候才被采用.关于 RCU 机制,这里就不做过多的介绍了,网上有很多有关 RCU 介绍和使用的文档.请自行查阅.本文主要是从 linux kernel 源代码的角度.来分析 RCU 的实现. 在讨论 RCU 的实现之前.有必要重申以下几点: 1:RCU 使用在读者多而写者少的情况.RCU 和读写锁相似.但 RCU 的读者占锁没有任何的系统开销.写者与写写者之间必须要保持同步,且写者必须要等它之前的读者全部都退出之后才能释放之前的资源. 2:RCU 保护的是指针.这一点尤其重要.因为指针赋值是一条单指令.也就是说是一个原子操作.因它更改指针指向没必要考虑它的同步.只需要考虑 cache 的影响. 3:读者是可以嵌套的.也就是说 rcu_read_lock()可以嵌套调用. 4:读者在持有 rcu_read_lock()的时候,不能发生进程上下文切换.否则,因为写者需要要等待读者完成,写者进程也会一直被阻塞. 以下的代码是基于 linux kernel 2.6.26 二:使用 RCU 的实例 Linux kernel中 自 己 附 带 有 详 细 的 文 档 来 介 绍RCU, 这 些 文 档 位 于linux-2.6.26.3/Documentation/RCU. 这些文档值得多花点时间去仔细研读一下. 下面以 whatisRCU.txt 中的例子作为今天分析的起点: struct foo { int a; char b; long c; }; DEFINE_SPINLOCK(foo_mutex); struct foo *gbl_foo; void foo_update_a(int new_a) { struct foo *new_fp; struct foo *old_fp; new_fp = kmalloc(sizeof(*new_fp), GFP_KERNEL); spin_lock(&foo_mutex); old_fp = gbl_foo; *new_fp = *old_fp; new_fp->a = new_a; rcu_assign_pointer(gbl_foo, new_fp); spin_unlock(&foo_mutex); synchronize_rcu(); kfree(old_fp); } int foo_get_a(void) { int retval; rcu_read_lock(); retval = rcu_dereference(gbl_foo)->a; rcu_read_unlock(); return retval; } 如上代码所示,RCU 被用来保护全局指针struct foo *gbl_foo. foo_get_a()用来从RCU 保护的结构中取得gbl_foo 的值.而foo_update_a()用来更新被RCU 保护的gbl_foo 的值. 另外,我们思考一下,为什么要在 foo_update_a()中使用自旋锁 foo_mutex 呢? 假设中间没有使用自旋锁.那 foo_update_a()的代码如下: void foo_update_a(int new_a) { struct foo *new_fp; struct f...