c++multithreadingconcurrencymemory-fences

Memory semantics of initialization in multithread environment (C++)


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?


Solution

  • 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]