How do you ensure newly constructed immutable objects are safely shareable amongst threads in C++? Does the C++ memory model provide guarantees about the operations of constructors?
When you have multiple threads that share access to an object, and the object is modified, race hazards are possible. Those problems can be avoided by safely publishing the object to all threads (including all possible future threads), so all subsequent accesses to the object from any thread see the same object state, then refraining from modifying the object. Subsequent accesses to the object will be immune to race hazards without using locks (mutexes). In the extreme case, the object is immutable: once constructed, it is never changed. There is therefore an idiom of using immutable objects as much as possible in multi-threaded programs.
That still leaves the need to safely publishing the object after code in the constructor has executed. The code executed by the constructor assigns values to memory locations, but those written values might (initially) exist only in the local cache of the CPU, for example. Other threads that accessed those memory locations might see old values that were recorded at those memory locations (such as a pattern of 0x00 bytes set up by malloc
, for example). There must be a mechanism to flush the local cache and invalidate the caches of the other CPUS, for the memory locations covered by the newly constructed object.
When programming a high level portable programming language, like C++, you do not concern yourself with the details of caches and cache flushing. Instead the language provides a set of guarantees (the memory model), and you have to write your code according to some idioms to reliably achieve your objective.
In Java, this is automatically done by following some rules in your class design (to over simplify: make everything final
, which is somewhat like const
in C++), which the Java memory model guarantees will result in the desired effect. This might be implemented by having a memory-barrier immediately after executing the code of the constructor.
How is this done in C++11? Does the C++ memory model provide guarantees about the operations of constructors, which enable you to automatically publish a newly constructed object? If so, what are the rules for your classes? And if not, and you have to add a memory barrier yourself (as you apparently have to do for .Net), is there is a idiom for efficiently publishing the object after construction?
Or does C++11 not provide thread-safe lock-free access to immutable objects? Must you guard all access to shared objects (immutable or not) with mutexes?