【问题标题】:Should I use compare_exchange_weak(or strong) when check atomic<bool> variable is set?设置检查 atomic<bool> 变量时是否应该使用 compare_exchange_weak(或 strong)?
【发布时间】:2026-02-10 11:50:01
【问题描述】:

下面的代码是 c++ concurrency in action 第 5 章中atomic&lt;bool&gt; 的使用示例。 为什么他们使用 compare_exchange_weak 来检查 b 是否设置,为什么他们在 while 循环中使用!expected

bool expected=false;
extern atomic<bool> b; // set somewhere else
while(!b.compare_exchange_weak(expected,true) && !expected);

我可以把上面的代码改成下面这样的简单代码吗?

extern atomic<bool> b; // set somewhere else
while(!b.load());

【问题讨论】:

  • 他们的代码将标志设置为真。看起来几乎等同于 b = true; 没有循环。

标签: c++ concurrency c++14 compare-and-swap


【解决方案1】:

哇,这是一段令人困惑的代码。首先显而易见的一点是, compare_exchange_weak 版本(可能)会改变底层原子值的值。 b.load() 没有,所以它们不等价。

解释一下……

while(!b.compare_exchange_weak(expected,true) && !expected);

b.compare_exchange_weak(expected,true) 说

如果 b 为假,则使其为真,否则设置预期 = b(true)

现在你可能会问,为什么兑换后代码检查值?
它正在检查另一个线程是否已经设置了该值。这导致循环退出。但是,如果无论 b 的值是多少,代码都会退出,为什么要循环呢?

存在循环是因为该函数的弱版本什么都不做(无缘无故)。

所以这段代码等价于

b.compare_exchange_strong(预期,真);

我不确定作者为什么不这样写,但我错过了它的上下文。如果有人将其放入生产代码中,而上面没有很好的解释性注释,我肯定会遇到问题!

详情请参阅https://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange。 类似讨论见https://newbedev.com/understanding-std-atomic-compare-exchange-weak-in-c-11

【讨论】:

  • 你的意思是虚假唤醒。那么,while(!b.compare_exchange_weak(expected,true) && !b.load()); 怎么样? ?不是更清楚吗?
  • 原子负载可能更昂贵,所以我会说从功能上讲这是正确的,但速度较慢。我不确定它是否有助于理解。一般来说,如果可能的话,更喜欢 std-lib 函数。作者可能出于某种原因避免使用此功能,但如果是这样,他们应该解释一下。