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

时间:2018-12-05 00:48:51

标签: c++ mutex atomic stdatomic stdmutex

阅读std::condition_variable的文字时,我碰到了这句话:

  

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

我的问题是这个:

如果不是“用于POD的无锁代码”,原子对原子有什么用?

更新

看起来我的问题有些困惑:(

引用文本中的“共享变量”与“条件变量”不同。在同一页面上看到以下报价:

  

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

请不要回答“ why we need to use a mutex with condition variables”或“ how the conditional wait works”,而应提供有关互斥锁的使用如何“正确地发布”对等待线程的原子修改的信息,即是否像++counter;这样的表达式(不是if(counter == 0)这样的测试)需要在互斥下完成吗?

2 个答案:

答案 0 :(得分:4)

条件等待的语义使得必须使用互斥锁。

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

  1. 获取独占锁
  2. 执行测试
  3. 任一:

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

    b)保持锁定并继续

由于第1步获得了一个锁,如果所有其他方都正确使用了互斥锁,则整个过程都是原子的。

但是当要修改的变量是原子时该怎么办?

  

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

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

答案 1 :(得分:1)

  

如果[条件变量]仍然需要互斥才能正常工作,为什么要使用std :: atomic

没有理由使用原子条件变量。

  

原子有什么用

即使原子对条件变量没有用,它们仍然对其他用例有用。原子的典型用例是实现无锁队列。