How to implement multithread safe singleton in C++11 without using <mutex>
Solution 1:
C++11 removes the need for manual locking. Concurrent execution shall wait if a static local variable is already being initialized.
§6.7 [stmt.dcl] p4
If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
As such, simple have a static
function like this:
static Singleton& get() {
static Singleton instance;
return instance;
}
This will work all-right in C++11 (as long as the compiler properly implements that part of the standard, of course).
Of course, the real correct answer is to not use a singleton, period.
Solution 2:
Maybe the easiest way to implement a singleton using C++11 is:
WARNING: Although this works according to the C++11 standard (static initialisers are thread-safe), this is not implemented correctly in Microsoft Visual C++ 2012 (static initialisers are NOT thread-safe). If you are targeting VC2012, then you have to use a different approach, as it does not fully implement the C++11 standard.
class Singleton {
public:
static Singleton& Instance() {
// Since it's a static variable, if the class has already been created,
// it won't be created again.
// And it **is** thread-safe in C++11.
static Singleton myInstance;
// Return a reference to our instance.
return myInstance;
}
// delete copy and move constructors and assign operators
Singleton(Singleton const&) = delete; // Copy construct
Singleton(Singleton&&) = delete; // Move construct
Singleton& operator=(Singleton const&) = delete; // Copy assign
Singleton& operator=(Singleton &&) = delete; // Move assign
// Any other public methods.
protected:
Singleton() {
// Constructor code goes here.
}
~Singleton() {
// Destructor code goes here.
}
// And any other protected methods.
}
Solution 3:
IMHO, the best way to implement singletons is with a "double-check, single-lock" pattern, which you can implement portably in C++ 11: Double-Checked Locking Is Fixed In C++11 This pattern is fast in the already-created case, requiring only a single pointer comparison, and safe in the first-use case.
As mentioned in previous answer, C++ 11 guarantees construction-order safety for static local variables Is local static variable initialization thread-safe in C++11? so you are safe using that pattern. However, Visual Studio 2013 does not yet support it :-( See the "magic statics" row on this page, so if you are using VS2013 you still need to do it yourself.
Unfortunately, nothing is ever simple. The sample code referenced for the pattern above cannot be called from CRT initialization, because the static std::mutex has a constructor, and is thus not guaranteed to be initialized before the first call to get the singleton, if said call is a side-effect of CRT initialization. To get around that, you have to use, not a mutex, but a pointer-to-mutex, which is guaranteed to be zero-initialized before CRT initialization starts. Then you would have to use std::atomic::compare_exchange_strong to create and use the mutex.
I am assuming that the C++ 11 thread-safe local-static-initialization semantics work even when called during CRT initialization.
So if you have the C++ 11 thread-safe local-static-initialization semantics available, use them. If not, you have some work to do, even moreso if you want your singleton to be thread-safe during CRT initialization.