# 什么是RCU：用法
Date: 2019-06-12


这篇文章  [What is RCU? Part 2: Usage](https://lwn.net/Articles/263130/)

作者：

_**Paul E. McKenney,** IBM Linux Technology Center_ ，

这篇文章主要通过与几以下几类机制的比较，深入对RCU进行了分析：

1. RCU与读写锁机制；
2. RCU是一种严格引用计数机制 Restricted Reference-Counting Mechanism
3. RCU与GC机制；
4. RCU与Existence guarantees（出自论文[Gamsa等。\[PDF\]](http://www.usenix.org/events/osdi99/full_papers/gamsa/gamsa.pdf)）
5. RCU是一种事件等待机制；

RCU优势：

- 性能优势：实验中与读写机制rwlock比较， 随着CPU增加RCU CPU开销没有明显增长；
- 死锁免疫（Deadlock Immunity）：由于读取端没有阻塞， 理论上不会有死锁。
- 实时性、低延时：同样也是由于RCU读端的不阻塞，使他有更出色的实时性和低延时。
- RCUreader与updater同时运行![Comparison of RCU and rwlock update latency.](https://lwn.net/images/ns/kernel/rcu/rwlockRCUupdate.jpg)

rwlock保证读者总是读到更新后的数据， 但是作者也提到了现实中类似路由表的应用， 对于旧数据影响并时不时很大，而rwlock这种机制也依赖于reader/writer优先级的设定

- 可以方便的替换rwlock

```
 1 struct el {                          1 struct el {
 2   struct list_head list;             2   struct list_head list;
 3   long key;                          3   long key;
 4   spinlock_t mutex;                  4   spinlock_t mutex;
 5   int data;                          5   int data;
 6   /* Other data fields */            6   /* Other data fields */
 7 };                                   7 };
 8 rwlock_t listmutex;                  8 spinlock_t listmutex;
 9 struct el head;                      9 struct el head;

```

```
 1 int search(long key, int *result)    1 int search(long key, int *result)
 2 {                                    2 {
 3   struct list_head *lp;              3   struct list_head *lp;
 4   struct el *p;                      4   struct el *p;
 5                                      5
 6   read_lock(&listmutex);             6   rcu_read_lock();
 7   list_for_each_entry(p, head, lp) { 7   list_for_each_entry_rcu(p, head, lp) {
 8     if (p->key == key) {             8     if (p->key == key) {
 9       *result = p->data;             9       *result = p->data;
10       read_unlock(&listmutex);      10       rcu_read_unlock();
11       return 1;                     11       return 1;
12     }                               12     }
13   }                                 13   }
14   read_unlock(&listmutex);          14   rcu_read_unlock();
15   return 0;                         15   return 0;
16 }                                   16 }

```

```
 1 int delete(long key)                 1 int delete(long key)
 2 {                                    2 {
 3   struct el *p;                      3   struct el *p;
 4                                      4
 5   write_lock(&listmutex);            5   spin_lock(&listmutex);
 6   list_for_each_entry(p, head, lp) { 6   list_for_each_entry(p, head, lp) {
 7     if (p->key == key) {             7     if (p->key == key) {
 8       list_del(&p->list);            8       list_del_rcu(&p->list);
 9       write_unlock(&listmutex);      9       spin_unlock(&listmutex);
                                       10       synchronize_rcu();
10       kfree(p);                     11       kfree(p);
11       return 1;                     12       return 1;
12     }                               13     }
13   }                                 14   }
14   write_unlock(&listmutex);         15   spin_unlock(&listmutex);
15   return 0;                         16   return 0;
16 }                                   17 }

                   example taken from Wikipedia.

```

- 可以方便的替换rwlock
- 参考计数机制 Reference-Counting Mechanism：看上去和rwlock模式一致

```
 
 1 rcu_read_lock();  /* acquire reference. */
  2 p = rcu_dereference(head);
  3 /* do something with p. */
  4 rcu_read_unlock();  /* release reference. */
```

```
  1 spin_lock(&mylock);
  2 p = head;
  3 head = NULL;
  4 spin_unlock(&mylock);
  5 synchronize_rcu();  /* Wait for all references to be released. */
  6 kfree(p);
```

但是由于要求读不阻塞， 所以在与rwlock进行性能比较时大概在4个cpu时rcu与rwlock的cpu开销已经趋于一致。

- RCU 批量参考计数机制，由于器轻量级的读取，对于大量数据结构生成锁这里还提到 SRCU

RCU的核心是提供以下功能的API：

1. 对新数据一个订阅发布机制；
2. 等待订阅这完成；
3. 多版本的发布不破坏现有订阅进程的并发读取。

作者认为 RCU可以应用于读写锁，引用计数，存在保证 等场景。

这篇文章是发表于2007年， 在后续linux kernel实践过程中遇到了很多实际问题， [RCU's First-Ever CVE, and How I Lived to Tell the Tale](http://www.rdrop.com/users/paulmck/rclock/cve.2019.01.23e.pdf)          这个演讲中描述了RCU 相关结构的演进，还有详细的修复CVE列表。

## 参考：

[Linux 2.6内核中新的锁机制--RCU](https://www.ibm.com/developerworks/cn/linux/l-rcu/index.html)

