背景: #
多线程同步时,加锁是一种简单有效的方式,但是会有性能损失。 无锁机制可以有效的避免性能损失,常见的无锁机制包括:
- 原子操作
- 原子变量
- CAS原语
- RCU
- seqlock
PS:这里的无锁机制指的是优化过的锁。
RCU Read Copy Update #
主要是利用的逻辑上的hack:
当要对数据data进行写操作时:
- 先申请一个temp变量
- 拷贝data到temp
- 对temp进行写操作
- 拷贝temp到data(保证原子)
- 释放之前的data(需等待所有读取线程结束)
在上述步骤中,不会影响到读线程, 读线程只会读到 “没有修改过的” or “修改之后的” data, 永远不会读取到 “修改了一半"的data, 造成错误。
所以RCU的特点是,或者说RCU锁的特点是:
- 多个线程一起读
- 单个线程写
- 读写可以并行
因此RCU的用法如下:
//读线程
rcu_read_lock();
a = somedata;
rcu_read_unlock();
//写线程
spin_lock(); //spin_lock是可选的,如果只有一个线程在写入,不需要spin_lock
some_data = new_data;
synchronize_rcu(); //此函数会等待目前所有的rcu_read_unlock()
free(old_data)
spin_unlock();