You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

《C++ Concurrency in Action》无锁队列push中for循环及CAS操作疑惑

关于《C++ Concurrency in Action(第二版)》无锁队列push函数的两个疑问解答

一、for(;;)循环的实际作用

这是无锁编程里的自旋重试逻辑。无锁队列面向多线程并发场景,当你尝试用CAS操作修改共享变量(比如节点指针、tail指针)时,很可能因为其他线程同时修改这些变量导致CAS失败。这个无限循环会让当前线程不断重新获取队列的最新状态,再重复执行插入流程,直到整个push操作成功完成。

举个场景:你刚读取到tail的旧值,准备修改它的next指针,结果另一个线程抢先更新了tail,此时你的CAS就会失败,必须重新读取最新的tail,再走一遍插入步骤——这个循环就是干这个的,保证操作最终能完成(只要系统中没有线程挂起卡死)。

二、为什么要用old_data=nullptr去CASold_tail.ptr->data

首先得明确这个无锁队列的设计细节:队列的tail指针始终指向一个"哨兵节点"——这个节点的data字段是nullptr,专门作为新元素的插入占位符。

执行push时,第一步就是尝试把这个哨兵节点的data从nullptr替换成待插入的新数据:

  • old_data初始化为nullptr,是为了确认当前节点确实还是未被占用的空哨兵节点(没有被其他线程抢先使用)。
  • 这个CAS的核心作用是原子性抢占插入位置:如果CAS成功,说明我们拿到了该节点的使用权,可以存入新数据;如果CAS失败,说明其他线程已经把数据放到这个节点里了,我们需要重新获取最新的tail,换节点重试。

等这个CAS成功后,还要创建一个新的空哨兵节点,将其设为当前节点的next,最后更新tail指针指向这个新哨兵——这样下一次push时就有了新的占位符。

内容的提问来源于stack exchange,提问作者YuerWu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 04:57:05