I am not certain of the memory semantics of C++ initialization process. Let's say we have the following program.
#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;
}
Will the new thread see an array initialized properly? Or do I need the insert some sort of memory barrier in between. How does C++ language define the memory semantics for the initialization?
My concern is that all the writes to array a[10] may sit in one cpu's write buffer, and we start a new thread on a different cpu, which may not observe the initialization writes.
Do we need memory fence for initialization to be able to be observed by later issued thread running on a different cpus?
There is a "happens-before" relationship between operations in the parent prior to executing the thread constructor, and the thread procedure running in the child. In particular the Standard says (f
being the thread procedure):
Synchronization: The completion of the invocation of the constructor synchronizes with the beginning of the invocation of the copy of
f
.
This is found in section [thread.thread.constr]