请考虑以下代码段。
T data;
T* ptr1 = &data;
T* ptr2 = &data;
*ptr1 = ...;
std::thread thread([ptr2]() {
*ptr2 = ...;
});
thread.join();
问:它引入了数据竞赛吗?
我的想法:因为ptr1
和ptr2
是不同的变量,所以赋值和按值捕获都需要重新排序。因此,数据竞争就在那里。
它是否正确?
线程创建意味着在关系之前发生,即,给定代码中没有数据争用。事实上,*ptr1
的任务实际上发生在下一个声明之前。如果您在创建线程后重新排序代码以分配给*ptr1
,那么您将拥有数据竞争:使用哪个指针引用来访问对象以创建数据竞争并不重要。
我认为这里不会有比赛。在创建新线程之前,程序运行单线程,因此执行顺序将由您编写。
Here's关于编译时内存排序的解释。
这个页面引用了一句好话:
The cardinal rule of memory reordering, which is universally followed by compiler developers and CPU vendors, could be phrased as follows:
Thou shalt not modify the behavior of a single-threaded program.