Skip to content

无锁并发

无锁并发技术是在不使用锁的情况下解决并发问题的技术,区别于锁机制,往往性能更加高效。使用锁往往容易导致死锁问题。

其优点包括:

  • 避免死锁和优先级反转
  • 提高并发性能,减少上下文切换
  • 适合高性能、低延迟场景

原子操作

依赖于硬件级别的能力,基于原子指令,对单一变量进行并发保证,可以基于此设计无锁队列和无锁环等数据结构,拥有极高的性能,且没有死锁。见原子操作

  • CAS(Compare-And-Swap):最常用的无锁原语,广泛用于实现无锁队列、无锁栈等数据结构。CAS 思想是指,当希望修改一个值的时候,尝试先进行值的比较,如果当前的数字的值是预期值,则使用新的值替换它,否则失败,并且比较和替换的操作是通过原子指令保证不可打断;所以,很多时候在使用 CAS 的时候,我们会将它放在一个死循环中,让 CPU 陷入忙等重试,重复执行 CAS 操作,直到成功,由于该操作非常快,其实失败的概率并不大。
  • 原子计数器:如引用计数、统计计数等。
  • 环形缓冲区、无锁队列:常用于内核、网络、日志等高并发场景。

自旋忙等

实现简单,但是延迟较高。CPU 需要一定的消耗。

c
while(!is_condition()) {
   sleep(8000); // 8ms
}

RCU

Read-Copy-Update 机制,在 Linux 系统广泛使用,对于读者来说支持共享读,对于写者来说,自己创建一个副本,然后修改,修改完之后再替换原本的数据,高并发读场景中的无锁利器。但是,写慢读快,延迟回收。

消息传递

不共享变量,从源头上解决问题——使用通信来共享内存,而不是通过共享内存来通信。

实践中,往往使用 MessageChannel 对象来传递信息,而不是让不同线程直接去访问共享内存。