阅读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)
这样的测试)需要在互斥下完成吗?
答案 0 :(得分:4)
条件等待的语义使得必须使用互斥锁。
这是因为正在测试条件的线程上存在潜在的竞争条件。当该线程正在检查是否等待时,会发生以下情况:
任一:
a)释放锁定并等待下一个信号
b)保持锁定并继续
由于第1步获得了一个锁,如果所有其他方都正确使用了互斥锁,则整个过程都是原子的。
但是当要修改的变量是原子时该怎么办?
即使共享变量是原子变量,也必须在互斥锁下对其进行修改,以便正确地将修改发布到等待线程。
嗯,这就是原因。如果线程B出现并在互斥锁外部修改了原子,则步骤2和3不再是原子的。本质上,线程B可以在步骤2发生后立即修改该值。然后线程A在步骤3中可能会做出错误的决定。
答案 1 :(得分:1)
如果[条件变量]仍然需要互斥才能正常工作,为什么要使用std :: atomic
没有理由使用原子条件变量。
原子有什么用
即使原子对条件变量没有用,它们仍然对其他用例有用。原子的典型用例是实现无锁队列。