lock-free数据结构

探讨无锁数据结构的设计与实现,特别是无锁循环数组队列,对比传统加锁方法,解决ABA问题,适用于多线程环境中写少读多场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Lock-Free 学习总结

参考文章

  1. Lock-Free Data Structures, Andrei Alexandrescu, 2004
  2. Lock-Free Data Structures with Hazard Pointers, Andrei Alexandrescu, Maged Michael, 2004
  3. Implementing Lock-Free Queues, John D, Valois, 1994
  4. Yet another implementation of a lock-free circular array queue, Faustino Frechilla, 2011

 

Yet another implementation of a lock-free circular array queue, Faustino Frechilla, 2011

(本地无图版)

Cache Trashing: 切换thread的开销:1.上下文Save&Load;2.Cache被其他线程覆盖;

传统mutex+cond方法,对IsEmpty和Push和Pop都加锁;

文献里的方法,用的链表和CAS lock-free,会有ABA问题;

解决ABA问题,一种方法是自己实现堆内存管理,申到的内存块有计数;一种方法是不是用堆内存;

本文用循环数组,实现有size上限的lock-free队列,不惧怕ABA问题;

用了3个index: readIndex, writeIndex, maxReadIndex; Push操作先把writeIndex加1,再在原writeIndex位置写入数据,再将maxReadIndex加1;类似2阶段提交;

之所以在Write的第2阶段的循环里进行了类似Sleep(0)的让出CPU,是因为当多个Push线程要在这一个CPU核上执行时,自己堵着执行顺序靠前的线程,会造成更多时间开销的浪费;

由于第2阶段的提交需要按第一阶段的顺序来走,多了等待的可能性,所以和glib的mutex阻塞版本相比,本lock-free版本更适合只有1个线程写入,或者1个线程忙碌写入的情况下,比mutex版本快1倍;2个忙写线程就比mutex慢个10%了,3个忙些线程比mutex版本慢1倍;

lock-free的难点,在于:1. 要考虑任何时刻当前线程被换出打断,会不会造成数据一致性的错误;2.要考虑任何时刻当前线程挂掉了,其他线程能不能不受影响继续正确的逻辑;

 

Lock-Free Data Structures, Andrei Alexandrescu, 2004

加锁的缺点:1.在临界区进行IO操作会让别的线程更久的等待;2.多个锁时,容易造成死锁;

本篇论文没有考虑Memory Barrier的问题,假设都是按顺序访问的;

wait-free: 任意线程都可以在有限步数內完成操作;lock-free:所有线程里肯定有线程能往前走一步,不保证任意线程都能往前走;

live-lock: 2个人狭路相逢,积极躲对方但总是和对方躲到一处,2个线程都没block,但就是过不去;夫妻吃饭互相礼让勺子

wait-free和lock-free的好处:1. 任意线程突然挂掉,不影响其他线程的进度继续;2.类似malloc这样加了锁后被中断,则在中断程序里不敢再调用malloc了;3.加锁的话,低优先级线程占有了锁,高优先级线程也去要,产生优先级反转,即OS必须先执行低优先级线程;

实现“写少读多”map(系统要有GC支持):  1. 读直接读;2.写则把老map复制到新map, 往新map写入,最后CAS(if pMap==pOld then pMap<=pNew,return true else return flase);  3. 老map必须在没有别的线程正在读,才能自动被GC回收;

如果没有GC支持,则可采用引用计数方式:1. 读的时候用CAS把计数加1,读,再用CAS减1;2.写的时候用CAS赋值新指针(看整个pair是否变化,即pMap没变化且count为1,则赋值新指针);  巧妙之处是把pMap和count放到同一个pair里,64位,在一个CAS里可以操作;缺点是读太多的话,写操作就饿死了;

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值