【发布时间】:2017-12-20 11:30:03
【问题描述】:
考虑以下 sn-p。
T data;
T* ptr1 = &data;
T* ptr2 = &data;
*ptr1 = ...;
std::thread thread([ptr2]() {
*ptr2 = ...;
});
thread.join();
问题:它会引入数据竞争吗?
我的想法:由于ptr1 和ptr2 是不同的变量,因此赋值和按值捕获需要重新排序。因此,存在数据竞赛。
这是正确的吗?
【问题讨论】:
-
怎么可能?线程在第一次修改后生成。该执行仍在按顺序执行。
-
@StoryTeller 啊哈,这就是我错过的!产生一个线程至少会引入一个内存栅栏。对吗?
-
"[线程的]构造函数调用的完成与(定义在std::memory_order中)在新的f的副本的调用开始同步执行线程。”来自这里:en.cppreference.com/w/cpp/thread/thread/thread
-
@RichardCritten 但这不仅仅意味着线程执行的开始发生在构造 lambda 之后。而且由于第 4 行的赋值和 lambda 的构造函数是未排序的(或者我在这里错过了什么?),这并不能回答我的问题。
-
@SolenodonParadoxus - 它实际上比这更基本。
*ptr1 = ...;和thread的声明是 two full expressions sequenced in a particular order。根据抽象机器本身,一个必须在另一个之前完全发生。编译器无法真正进行会改变这一点的转换。
标签: c++ c++11 memory thread-safety