如果仍然需要互斥锁才能正常工作,为什么要使用 std::atomic

YeP*_*IcK -1 c++ mutex atomic stdatomic stdmutex

阅读文本,因为std::condition_variable我遇到了这句话:

即使共享变量是原子的,也必须在互斥锁下进行修改,才能将修改正确发布到等待线程。

我的问题是这样的:

如果不是“与 POD 一起工作的无锁代码”,原子有什么用?

更新

看起来我的问题有些混乱:(

引用文本中的“共享变量”与“条件变量”不同。请参阅同一页面中的此引用:

...直到另一个线程同时修改共享变量(条件),并通知condition_variable

请不要回答“为什么我们需要使用带有条件变量的互斥锁”或“条件等待如何工作”,而是提供有关互斥锁的使用如何“正确发布”对等待线程的原子修改的信息,即是否需要在互斥锁下完成像++counter;而不是像测试if(counter == 0))这样的表达式?

pad*_*ddy 7

条件等待的语义需要使用互斥锁。

这是因为在测试条件的线程上存在潜在的竞争条件。当该线程检查是否等待时,会发生以下情况:

  1. 获取排他锁
  2. 进行测试
  3. 任何一个:

    a) 释放锁并等待下一个信号

    b) 保持锁定并继续

因为第 1 步获取锁,所以整个事情是原子的,前提是所有其他方都正确使用互斥锁。

但是当被修改的变量是原子的时候呢?

即使共享变量是原子的,也必须在互斥锁下进行修改,才能将修改正确发布到等待线程。

嗯,这就是原因。如果线程 B 出现并修改互斥锁之外的原子,则步骤 2 和 3 不再是原子的。本质上,线程 B 可以在步骤 2 发生后立即修改该值。那么线程 A 可能会在步骤 3 中做出错误的决定。