Christopher Simmons
Christopher Simmons

Reputation: 1048

C++ memory semantics and globals that are set at the start of a program

If I have one thread, the "main" thread, initialize a global variable and that thread later spawns some threads that access that variable, do I need to do any work, such as a call to std::atomic_thread_fence(memory_order_seq_cst), to guarantee that the variable appears initialized to the new threads? I suspect that the fact that the main thread creates the new threads establishes a "synchronized-with" relationship that is sufficient to prevent any races, but I'm not certain.

Here's some pseudocode for what I'm describing:

class MyApi {
public:
    static void init(Foo *foo) {
        MyApi::foo = foo;
    }

    static Foo* getSharedFoo() {
        return foo;
    }

private:
    static Foo* foo;
};

void main() {
    Foo* foo = new Foo();
    MyApi::init(foo);
    // Spawn threads that will call MyApi::getSharedFoo() and expect
    // to receive the same foo that is created above.
}

Upvotes: 3

Views: 51

Answers (2)

Sam Varshavchik
Sam Varshavchik

Reputation: 118435

30.3.1.2 thread constructors

[ ... ] template explicit thread(F&& f, Args&&... args);

[ ... ]

Synchronization: The completion of the invocation of the constructor synchronizes with the beginning of the invocation of the copy of f.

This specifies that f sees everything that occurred prior to the construction of the std::thread object that spawned the thread.

Upvotes: 0

Pete Becker
Pete Becker

Reputation: 76498

No, you don't have to do anything special. New threads see all memory changes up to the point where they were constructed.

Upvotes: 2

Related Questions