q09*_*987 9 c++ concurrency c++11
当两个线程同时访问同一个变量并且至少有一个访问是写入时,就会发生数据争用.
https://isocpp.org/wiki/faq/cpp11-language-concurrency
// start with x==0 and y==0
if (x) y = 1; // Thread 1
if (y) x = 1; // Thread 2
Run Code Online (Sandbox Code Playgroud)
这里有问题吗?更确切地说,是否有数据竞争?(不,没有).
为什么原始文章声称这里没有数据竞争?
Nic*_*las 11
数据争用不是代码的静态属性.它们是执行时程序实际状态的属性.因此,虽然该程序可能处于代码会产生数据竞争的状态,但这不是问题.
问题是,鉴于系统的状态,代码会导致数据竞争吗?并且由于程序处于这样的状态,即两个线程都不会写入任何变量,因此代码不会导致数据竞争.
数据竞争与您的代码可能做的事情无关.这是他们将要做的事情.就像一个接受指针的函数不是未定义的行为,因为它使用指针而不检查NULL.如果有人传递一个真正为NULL的指针,那么它只是UB.
因为x并且y都是零,所以由C++标准定义的抽象机器不能写入任何一个内存位置,因此这可能是一个问题的唯一方法是实现决定写入内存位置.例如,如果它改变了
if (x) y = 1;
Run Code Online (Sandbox Code Playgroud)
成
y = 1;
if (!x) y = 0;
Run Code Online (Sandbox Code Playgroud)
这是as-if规则下可能有效的重写,因为任何一个线程观察到的行为都是相同的(C++ 14 1.9 [intro.execution])
本国际标准中的语义描述定义了参数化的非确定性抽象机器.本国际标准对符合实施的结构没有要求.特别是,它们不需要复制或模拟抽象机器的结构.相反,需要符合实现来模拟(仅)抽象机器的可观察行为,如下所述.
事实上,这在C++ 11之前是有效的重写,但是从C++ 11开始,考虑了执行的线程.因此,只要抽象机器中不发生数据争用,就不允许实现进行跨线程的不同观察行为的更改.
C++ 14标准中有一个特殊的注释适用于此处(C++ 14 1.10 [into.multithread]第22段)
[注意:此标准通常会排除将引用分配给可能由抽象机器修改的潜在共享内存位置的编译器转换,因为在抽象机器执行的情况下,这样的分配可能会覆盖另一个线程的另一个分配不会遇到数据竞争....
因此,重写无效.实施有保留,观察到的行为x,并y没有被修改,甚至是跨线程.因此,没有数据竞争.