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

compare_exchange循环是否可能陷入死循环?附无锁栈代码分析

解答:compare_exchange循环不会陷入死循环

首先明确你的判断是错误的,这个compare_exchange_weak的循环不会陷入死循环,核心原因在于compare_exchange_weak的行为特性,咱们结合代码和你描述的场景一步步分析:

先回顾compare_exchange_weak的核心行为

std::atomic::compare_exchange_weak的逻辑可以拆解为两点:

  • 拿原子变量的当前值和第一个参数(这里是old_head)比较:
    • 如果相等:把原子变量的值替换成第二个参数(old_head->next),返回true,循环直接退出
    • 如果不相等:自动把原子变量的当前最新值更新到第一个参数(old_head)里,返回false,进入下一次循环

针对你描述的场景逐步骤分析

假设初始栈的head指向节点A:

  1. 线程一执行Node* old_head = head.load();,此时old_head存储的是节点A的地址
  2. 线程一被时间片切换走,线程二执行push操作:
    • 创建新节点B,将B的next指向A
    • 通过原子操作把head从A替换为B,完成后head现在指向B
  3. 线程一回到CPU继续执行循环:
    • 第一次compare_exchange_weak:head当前值是B,和old_head(A)不相等,于是函数返回false,同时把old_head更新为B的地址
    • 进入下一次循环:此时old_head已经是B的地址,尝试将head从B替换为B->next(也就是A)。如果此时没有其他线程干扰这个操作,这次比较会成功,返回true,循环退出
    • 最后线程一取出old_head(节点B)的data,完成pop流程

额外补充:为什么要用循环包裹?

compare_exchange_weak可能出现伪失败(spurious failure)——也就是原子变量的值和expected参数相等,但因为硬件竞争或内存模型的原因,操作没成功返回false,所以需要循环重试。而即使是像你说的真实线程竞争场景,循环也会通过自动更新old_head到最新值来继续尝试,绝不会卡死。

另外提一句:你给出的pop代码有个潜在风险——当栈为空时,old_head会是nullptr,访问old_head->next会触发未定义行为,这是需要额外处理的边界情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 07:07:46