std :: atomic <int>减量和比较

And*_*uel 20 c++ concurrency multithreading atomicity c++11

在以下代码中:

std::atomic<int> myint; //Shared variable
//(...)
if( --myint == 0) {
    //Code block B
}
Run Code Online (Sandbox Code Playgroud)

是否有可能多个线程访问名为"代码块B"的块?

请考虑溢出不会发生,'if'由多个线程同时执行,整个程序中对myint的唯一修改是if中的--myintmyint初始化为正值.

Soa*_*Box 18

C++ 0x paper N2427(atomics)大致说明如下.我稍微改变了措辞,因此更容易阅读特定的减量情况,我改变的部分是粗体:

效果:以原子替换的对象与所述的结果减量施加到对象和给定的操作数.内存受订单影响.这些操作是在[由N2334或后继者添加的新部分]中的"与...同步"定义的意义上的读 - 修改 - 写操作,因此这样的操作和产生输入值的评估与任何评估同步.读取更新的值.

返回:原子地,在减量之前的对象的值.

原子操作保证递减运算符将返回变量在操作之前保持的值,这是原子的,因此另一个线程的更新不会有中间值.

这意味着以下是具有2个线程的此代码的唯一可能执行:

(Initial Value: 1)
Thread 1: Decrement 
Thread 1: Compare, value is 0, enter region of interest
Thread 2: Decrement
Thread 2: Compare, value is -1, don't enter region
Run Code Online (Sandbox Code Playgroud)

要么

(Initial Value: 1)
Thread 1: Decrement 
Thread 2: Decrement
Thread 1: Compare, value is 0, enter region of interest
Thread 2: Compare, value is -1, don't enter region
Run Code Online (Sandbox Code Playgroud)

案例1是无趣的预期案例.

情况2交织递减操作并稍后执行比较操作.因为递减和取指操作是原子的,所以线程1不可能接收0以外的值进行比较.它不能接收-1,因为操作是原子的...读取发生在递减时而不是在比较时.更多线程不会改变这种行为.

  • 请注意,我检查了N3291,虽然它使用了不同的措辞,但它同意这一点. (3认同)
  • @paulm如果你递减并签入两个不同的陈述,那绝对不是真的.必须在同一份声明中完成. (2认同)