C++多线程: Visible side-effects of non-atomic variables

标签 c++ c++11 language-lawyer lock-free stdatomic

C++ 标准中有一部分关于多线程内存模型我不明白。

A visible side effect A on a scalar object or bit-field M with respect to a value computation B of M satisfies the conditions:

  • A happens before B and

  • there is no other side effect X to M such that A happens before X and X happens before B.

The value of a non-atomic scalar object or bit-field M, as determined by evaluation B, shall be the value stored by the visible side effect A.

而且根据 C++ 标准,线程之间的“发生在”关系必须通过“同步”或“按依赖顺序”来建立before”,因此如果没有线程间同步,就不会建立“发生在”关系。

现在假设有两个线程 T1 和 T2,它们都由主线程启动,并且彼此之间从不进行任何同步(因此 T1 和 T2 之间不会建立任何“发生在”关系) T2)。如果 T1 写入非原子变量 M,那么根据上面的引用,T2 永远不会看到 M 被 T1 修改,因为不存在“发生在”关系T1 和 T2 之间。

相反,T2在T2启动时与主线程建立了“同步”关系,因此T2应该在主线程启动之前看到主线程设置的M值线程,因为主线程和 T2 之间存在“发生在”关系。

对吗?然而我在我的机器上做了实验,情况并非如此。怎么了?

最佳答案

T1 writes to a non-atomic variable M, then according to the quote above, T2 should never see M modified by T1

考虑以下因素:

Two actions are potentially concurrent if

  • they are performed by different threads, or

  • they are unsequenced, at least one is performed by a signal handler, and they are not both performed by the same signal handler invocation.

T2 对 M 的读取和 T1 对 M 的写入是“潜在并发的”。下一篇:

Two expression evaluations conflict if one of them modifies a memory location and the other one reads or modifies the same memory location.

T2 对 M 的读取与 T1 对 M 的写入发生冲突。因此这些“潜在并发”操作发生冲突。

最后,我们得出:

The execution of a program contains a data race if it contains two potentially concurrent conflicting actions, at least one of which is not atomic, and neither happens before the other, except for the special case for signal handlers described below. Any such data race results in undefined behavior.

T2 读取 M 不会发生在 T1 写入 M 之前,T1 写入 M 也不会发生在 T2 读取 M 之前。因此,会出现数据争用。

数据竞争是未定义的行为。这并不是说 T2 看不到对 M 的写入;而是说 T2 不会看到对 M 的写入。它可以看到任何东西:旧值、新值、某些第三值、发出的鼻守护进程,任何东西

关于C++多线程: Visible side-effects of non-atomic variables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61282738/

相关文章:

c++ - 终止模板搜索

c++ - 将 lambda 作为参数传递 - 通过引用或值?

c++ - 是否有自动 noexcept 说明符?

为 cout 取消引用指针时的 C++ SegFault

c++ - MATLAB 在执行半色调 mex 包装函数时崩溃?

c++ - 将 int 转换为枚举

c++ - 如何为模板特化设置别名?

c++ - enable_if 的句法模式

c++ - 为什么从流中提取字符串会设置 eof 位?

c++ - 转换为具有相同数据成员布局但实现不同的类是否安全?