c - 此示例是否包含数据竞争?

标签 c multithreading c++11 java-memory-model memory-model

这是原始问题,但我的与它有一些不同。 C++ memory model - does this example contain a data race?

我的问题:

//CODE-1: initially, x == 0 and y == 0
if (x) y++; // pthread 1
if (y) x++; // pthread 2

注意:上面的代码是用 C 编写的,而不是 C++(没有内存模型)。那么它是否包含数据竞争?

从我的角度来看:如果我们查看顺序一致性内存模型中的代码,则不会出现数据竞争,因为 x 和 y 永远不会同时为非零。然而,我们永远不能假设一个顺序一致性内存模型,所以编译器重新排序可以做出一个关于线程内正确性的转换,因为编译器不知道线程的存在......对吧?

所以代码可以转换为:
//CODE-2
y++; if (!x) y--;
x++; if (!y) x--;

上面的转换没有违反顺序正确性,所以它是正确的。这不是编译器的错,对吧?所以我同意CODE-1包含数据竞争的观点。你呢?

我有一个额外的问题,带有内存模型的 C++11 可以解决这个数据竞争,因为编译器知道线程,所以他们会根据内存模型类型进行重新排序,对吗?

最佳答案

C++ 标准将数据竞争(触发未定义行为)定义为:

§ 1.10.1-2 [intro.races]
Two expression evaluations conflict if one of them modifies a memory location (..) and the other one reads or modifies the same memory location.



根据 C++ 内存模型规则,您的第一个代码片段不包含数据竞争,因为 C++ 标准禁止会引入此类竞争的编译器转换:

§ 1.10.1-21 [intro.races]
Compiler transformations that introduce assignments to a potentially shared memory location that would not be modified by the abstract machine are generally precluded by this International Standard, since such an assignment might overwrite another assignment by a different thread in cases in which an abstract machine execution would not have encountered a data race.



所以它说如果 if 语句 ( x ) 中的条件产生 false,则不允许修改 y 的转换。 ,即使最终结果是 y显示未修改。

第二个示例显然包含数据竞争,因为 2 个线程可以写入和读取 x同时(同样适用于 y )。

请注意,从版本 11 开始,C++ 和 C 都有内存模型。如果您使用不支持 C11 的编译器,则未正式定义多线程行为。

这是一个 question这显示了非法编译器转换的示例。

关于c - 此示例是否包含数据竞争?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48109271/

相关文章:

c - 正确处理24小时时间

c - 如何用C检查闪存设备的坏扇区?

C++ 函数练习 - 不断返回零

c++ - std::scoped_lock 或 std::unique_lock 或 std::lock_guard?

c - 如何在 C 中动态分配二维数组?

c - 使用指针作为函数参数读取并显示姓名和年龄

java - `obj` 中的 `synchronized(obj) {...}` 参数的目的是什么?

java - Vector 中的竞争条件

c++ - 多线程应用程序中的访问冲突,C++

c++ - 如何确定 std::future 是否有值?