当两个线程同时访问相同的变量,并且至少有一个访问是写的时候,就会发生数据竞争。
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 这里有什么问题吗?更准确地说,是否存在数据竞争?(不,没有)。
为什么最初的文章声称这里没有数据竞争?
发布于 2017-02-13 20:50:50
因为x和y都是零,所以C++标准定义的抽象机器不能写入任何一个内存位置,所以这可能是唯一的问题,如果实现决定写到内存位置。例如,如果它转换了
if (x) y = 1;转到
y = 1;
if (!x) y = 0;这是在as-if规则下可能有效的重写,因为任何一个线程所观察到的行为都是相同的(C++14 1.9 intro.execution)
这个国际标准中的语义描述定义了一个参数化的非确定性抽象机器。本国际标准不对一致性实现的结构提出任何要求。特别是,它们不需要复制或模仿抽象机器的结构。相反,遵循实现需要(仅)模仿抽象机器的可观察行为,如下所述。
实际上,这在C++11之前是一个有效的重写,但是自从C++11之后,执行线程就会被考虑。因此,只要抽象机器中不发生数据竞争,实现就不允许进行跨线程的不同观察行为的更改。
在这里适用的C++14标准中有一个特别说明(C++14 1.10 into.multithread第22段)
[注意:将赋值引入到可能不会被抽象机器修改的共享内存位置的编译器转换通常被此标准所禁止,因为在抽象机器执行不会遇到数据竞争的情况下,这种赋值可能会用另一个不同的线程覆盖另一个分配。..。
正因为如此,重写是无效的。实现必须保留x和y未被修改的观察到的行为,即使跨线程也是如此。因此,不存在数据竞争。
发布于 2017-02-11 18:50:11
两个线程都不会写入,因为两个变量都不是条件值之前的非零变量。
发布于 2017-02-11 19:24:17
数据竞赛不是代码的静态属性。它们是程序在执行时的实际状态的属性。因此,虽然该程序可能处于代码会产生数据竞争的状态,但这不是问题。
问题是,考虑到系统的状态,代码会导致数据竞争吗?由于程序处于这样一种状态,即两个线程都不会写入任何一个变量,那么代码就不会导致数据竞争。
数据竞赛与您的代码可能会做什么无关。关键是他们会怎么做。就像接受指针的函数不是未定义的行为一样,仅仅是因为它使用指针而不检查NULL。只有当某人传递一个真正为NULL的指针时,才是UB。
https://stackoverflow.com/questions/42179740
复制相似问题