多线程环境(C+;+;)中初始化的内存语义 < >我不确定C++初始化过程的内存语义。 假设我们有以下程序 #include <iostream> #include <thread> using namespace std; void func(int* arr, int s) { for (int i = 0; i < s; ++i) { cout << arr[i] << endl; } } int main(int argc, char *argv[]) { int *a = new int[10]; for (int i = 0; i < 10; ++i) { a[i] = i; } // Do I need some sort of memory barrier here? std::thread t(func, a, 10); t.join(); return 0; } #包括 #包括 使用名称空间std; 无效函数(int*arr,int-s) { 对于(int i=0;i

多线程环境(C+;+;)中初始化的内存语义 < >我不确定C++初始化过程的内存语义。 假设我们有以下程序 #include <iostream> #include <thread> using namespace std; void func(int* arr, int s) { for (int i = 0; i < s; ++i) { cout << arr[i] << endl; } } int main(int argc, char *argv[]) { int *a = new int[10]; for (int i = 0; i < 10; ++i) { a[i] = i; } // Do I need some sort of memory barrier here? std::thread t(func, a, 10); t.join(); return 0; } #包括 #包括 使用名称空间std; 无效函数(int*arr,int-s) { 对于(int i=0;i,c++,multithreading,concurrency,memory-fences,C++,Multithreading,Concurrency,Memory Fences,在执行线程构造函数之前,父线程中的操作与子线程中运行的线程过程之间存在一种“发生在”关系。特别是标准规定(f为线程过程): 同步:构造函数调用的完成与f副本调用的开始同步 这可以在[thread.thread.constr]部分找到。感谢您的引用。我在阅读该标准时遇到了困难。我找到了您的引用。通过“与同步”,我想这意味着编译器可能会在调用f的副本之前插入fence,以确保调用f之前的所有存储都能被观察到?@OliverYoung:该标准没有提到任何关于内存fence的内容,因为并非所有CPU体系

在执行线程构造函数之前,父线程中的操作与子线程中运行的线程过程之间存在一种“发生在”关系。特别是标准规定(
f
为线程过程):

同步:构造函数调用的完成与
f
副本调用的开始同步


这可以在
[thread.thread.constr]

部分找到。感谢您的引用。我在阅读该标准时遇到了困难。我找到了您的引用。通过“与同步”,我想这意味着编译器可能会在调用f的副本之前插入fence,以确保调用f之前的所有存储都能被观察到?@OliverYoung:该标准没有提到任何关于内存fence的内容,因为并非所有CPU体系结构都需要它们。该标准说明了编译器需要确保哪一方e效果是可见的,并且在操作重叠的地方(创建竞争条件),编译器负责使用CPU功能提供的指定行为。我明白了。只是说得很清楚,初始化部分同步/“发生在”调用f的副本。这意味着不存在争用条件,也不需要同步操作,对吗?@OliverYoung:正确。尽管说“不需要额外的同步操作”更为正确,因为启动线程已经是一个同步操作,如本标准引用所述。