我有以下代码:
#include <thread>
void foo(int&){}
int main()
{
int value = 42;
std::thread t1([&value]{ foo(value); });
std::thread t2([&value]{ value = 100500; });
t1.join();
t2.join();
return 0;
}
常识告诉我们这里不存在数据竞争,因为通过引用传递值“必须”(???)是线程安全的,但我无法根据 cppreference 或标准草案来验证它N4950。
在没有前后顺序关系的情况下修改或读取相同的值是一种竞争条件。 (实际规则更复杂,但这足以避免竞争条件,并且在违反此规则的同时避免竞争条件非常具有挑战性)。
传递引用不会修改或读取某些内容。
因此,严格来说,您的代码没有竞争条件,因为两个线程中只有 1 个线程读取或写入您的变量。并修改变量 before,您将创建一个
std::thread
,修改它具有发生之前关系。
但是,如果
foo
对其参数做了任何不平凡的事情,你的代码会突然表现出未定义的行为。