c++ - 多个线程可以安全地同时向同一个变量写入相同的值吗?

标签 c++ multithreading thread-safety data-race

多个线程可以安全地同时向同一个变量写入相同的值吗?

举一个具体的例子 - C++ 标准是否保证以下代码能够在每个符合标准的系统上编译、运行而不会出现未定义的行为并打印“true”?

#include <cstdio>
#include <thread>

int main()
{
    bool x = false;
    std::thread one{[&]{ x = true; }};
    std::thread two{[&]{ x = true; }};
    one.join();
    two.join();
    std::printf(x ? "true" : "false");
}

这是一个理论问题;我想知道它是否总是有效,而不是它在实践中是否有效(或者像这样编写代码是否是一个好主意:))。如果有人能指出该标准的相关部分,我将不胜感激。根据我的经验,它在实践中总是有效的,但不知道它是否能保证有效,我总是使用 std::atomic 来代替 - 我想知道这对于这种特定情况是否是绝对必要的。

最佳答案

没有。

您需要通过使用互斥体或使它们原子化来同步对这些变量的访问。

写入相同值时没有异常(exception)。您不知道编写该值涉及哪些步骤(这是潜在的实际问题),标准也不知道,这就是代码具有未定义行为的原因……这意味着您的编译器可能会对您的程序造成绝对的困惑(这就是您需要避免的真正问题)。

有人会告诉你,这样那样的架构保证了对这些大小的变量的原子写入。但这并没有改变 UB 方面。

您要查找的段落是:

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

[intro.races/21]: […] The execution of a program contains a data race if it contains two potentially concurrent conflicting actions, […]. Any such data race results in undefined behavior.

...以及周围的措辞。该部分实际上非常深奥,但您实际上不需要解析它,因为这是一个经典的教科书数据竞赛,您可以在任何有关编程的书中读到。

关于c++ - 多个线程可以安全地同时向同一个变量写入相同的值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59655911/

相关文章:

c++ - 在 vector 上滑动 vector 的算法

c++ - 使用 C++ 和 SDL2 创建一个带有矩形的窗口

cocoa - NSThread 出现 _NSAutoreleaseNoPool 错误

java - 为什么这个 servlet 代码示例是线程不安全的?

java - 如何单独同步数据成员

c# - SqlConnection 线程安全吗?

c++ - 你如何从序列化数据中获取 'de-serialize' 的派生类?

c++ - 使用 HPET 时 QueryPerformanceFrequency 是否准确?

java - 两个线程在 "this"上同步调用增量方法,所用时间低于预期

java - 在for循环中创建许多不同的线程只产生一个线程(java)