这是一场数据竞赛吗?

Jan*_*Kim 4 c++ concurrency

volatile global x = 0;
reader() {
  while (x == 0) {}
  print ("World\n");
}
writer() {
  print ("Hello, ")
  x = 1;
}
thread (reader);
thread (writer);
Run Code Online (Sandbox Code Playgroud)

https://en.wikipedia.org/wiki/Race_condition#:~:text=Data%20race%5Bedit,only%20atomic%20operations

来自维基百科,

数据竞争的精确定义特定于所使用的正式并发模型,但通常它指的是这样一种情况:一个线程中的内存操作可能会在另一个线程中的内存操作被访问的同时尝试访问内存位置。在危险的情况下写入该内存位置。

  1. 至少有一个线程写入x。(作家)
  2. 至少有一个线程读取x。(读者)
  3. 没有任何用于访问x 的同步机制。(两个线程都无需任何锁即可访问x 。)

因此,我认为上面的代码是数据竞争。(显然不是竞争条件)我是对的吗?

那么当代码是数据竞争但它生成了预期的输出时,数据竞争的含义是什么?(我们将看到“Hello, World\n”,假设处理器保证对某个地址的存储对于存储指令之后发出的所有加载指令都可见)

----------- 添加了工作 cpp 代码 ------------

#include <iostream>
#include <thread>

volatile int x = 0;

void reader() {
    while (x == 0 ) {}
    std::cout << "World" << std::endl;
}

void writer() {
    std::cout << "Hello, ";
    x = 1;
}

int main() {
    std::thread t1(reader);
    std::thread t2(writer);
    t2.join();
    t1.join();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Hol*_*Cat 5

是的,这是一场数据竞赛和UB。

\n

[intro.races]/2

\n
\n

如果两个表达式求值之一修改内存位置,而另一个表达式求值读取或修改同一内存位置,则两个表达式求值会发生冲突。

\n
\n

[intro.races]/21

\n
\n

如果满足以下条件,则两个操作可能是并发的:
\n\xe2\x80\x94 它们由不同的线程执行,...

\n

...

\n

程序的执行包含数据竞争,其中至少一个操作不是原子操作,并且两者都发生在另一个操作之前,...

\n

任何此类数据竞争都会导致未定义的行为。

\n
\n

为了使不同线程中的两件事彼此“先发生”,必须涉及同步机制,例如非宽松原子、互斥锁等。

\n