I have been reading about thread safe singletons and the implementation I find everywhere has a getInstance() method something like this:
Singleton* getInstance()
{
if ( !initialized )
{
lock();
if ( !initialized )
{
instance = new Singleton();
initialized = true;
}
unlock();
}
return instance;
}
Is this actually thread safe?
Have I missed something or is there a small chance this function will return an uninitialized instance because 'initialized' may be reordered and set before instance?
This article is on a slightly different topic but the top answer describes why I think the above code is not thread safe:
Why is volatile not considered useful in multithreaded C or C++ programming?
Not a good idea. Look for double check locking. For instance:
http://www.drdobbs.com/cpp/c-and-the-perils-of-double-checked-locki/184405726
http://www.drdobbs.com/cpp/c-and-the-perils-of-double-checked-locki/184405772
It is indeed not thread safe, because after the pointer gets returned you still work with it, although the mutex is unlocked again.
What you can do is making the child class which inherits from singleton, thread safe. Then you're good to go.
Below is the code for a thread-safe singleton, using Double Check and temporary variable. A temporary variable is used to construct the object completely first and then assign it to pInstance.
Singleton* Singleton::instance() {
if (pInstance == 0) {
Lock lock;
if (pInstance == 0) {
Singleton* temp = new Singleton; // initialize to temp
pInstance = temp; // assign temp to pInstance
}
}
return pInstance;
}
Related
I have known that mutex can also bring the effect as memory barrier from here: Can mutex replace memory barriers, but I always see there is an memory barrier using in c++ singleton example as below, is the memory barrier unnecessary?
Singleton* Singleton::getInstance() {
Singleton* tmp = m_instance.load(std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_acquire);
if (tmp == nullptr) {
std::lock_guard<std::mutex> lock(m_mutex); // using mutex here
tmp = m_instance.load(std::memory_order_relaxed);
if (tmp == nullptr) {
tmp = new Singleton;
assert(tmp != nullptr);
std::atomic_thread_fence(std::memory_order_release); // using memory barrier here
m_instance.store(tmp, std::memory_order_relaxed);
}
}
return tmp;
}
If you can use C++11, you do not need to program your own protection.
As also referenced here, all the needed stuff is already part of C++11. Copied from there:
For the singleton pattern, double-checked locking is not needed:
If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
— § 6.7 [stmt.dcl] p4
Singleton& GetInstance() {
static Singleton s;
return s;
}
The implementation will provide a memory barrier or whatever to protect your concurrent access. So keep it simple as given in the example!
I have the following code:
MyClass.h:
static MyMutex instanceMutex;
static MyClass* getInstance();
static void deleteInstance();
MyClass.c:
MyMutex MyClass::instanceMutex;
MyClass* MyClass::getInstance()
{
if (theInstance == 0)
{
instanceMutex.acquire();
if (theInstance == 0)
{
theInstance = new MyClass();
}
instanceMutex.release();
}
return theInstance;
}
void MyClass::deleteInstance()
{
if (theInstance != 0)
{
instanceMutex.acquire();
if (theInstance != 0)
{
theInstance->finalize();
delete theInstance;
theInstance = 0;
}
instanceMutex.release();
}
return;
}
I have 2 questions on this:
Is the above code correct and safe?
After I call 'delete theInstance' in MyClass::deleteInstance(), I then call
theInstance = 0;
instanceMutex.release();
But if the instance is deleted than how is that even possible? isn't the memory of the class gone?
If it's a singleton - it is defined to have exactly one instance - if you delete it - this drops to 0
So it seems you should not support delete at all
Here be a problem:
if (theInstance == 0) // <- Some other thread might see a non-null theInstance
{ // before the constructor below returns
instanceMutex.acquire();
if (theInstance == 0)
{
theInstance = new MyClass(); // <- This might set theInstance to something
// before the constructor returns.
}
instanceMutex.release();
}
You may want to implement some sort of reference counting system (like using shared_ptr) and initializing it in a similar manner, though taking care to ensure that its instance pointer is not set before the initialization completes.
If you are feeling adventurous, you could also try:
if (theInstance == 0)
{
instanceMutex.acquire();
if (theInstance == 0)
{
MyClass * volatile ptr = new MyClass();
__FuglyCompilerSpecificFenceHintThatMightNotActuallyDoAnything();
theInstance = ptr; // <- Much hilarity may ensue if this write is not atomic.
}
instanceMutex.release();
}
This might fix it, and it might not. In the second case, it depends on how your compiler handles volatile, and weather or not pointer-sized writes are atomic.
In one project we inherited from some external company I've seen a whole nightmare class of errors caused by someone deleting the singleton. Perhaps in your rare case deleting the singleton doesn't have any side effects for the whole application, as you can be sure there is no instance of this singleton at use, but, generally, it's an excellent example of bad design. Someone could learn from your example and it would be a bad - even harmful - lesson. In case you need to clean up something in the singleton when the application exit, use the pattern ith returning reference to the singleton, like in example:
#include <iostream>
using namespace std;
class singleton {
private:
singleton() {
cout << "construktor\n";
}
~singleton() {
cout << "destructor\n";
}
public:
static singleton &getInstance() {
static singleton instance;
cout << "instance\n";
return instance;
}
void fun() {
cout << "fun\n";
}
};
int main() {
cout << "one\n";
singleton &s = singleton::getInstance();
cout << "two\n";
s.fun();
return 0;
}
I prefer to implement singletons in C++ in the following manner:
class Singleton
{
public:
static Singleton& instance()
{
static Singleton theInstance;
return theInstance;
}
~Singleton()
{
// Free resources that live outside the processes life cycle here,
// if these won't automatically be released when the occupying process
// dies (is killed)!
// Examples you don't have to care of usually are:
// - freeing virtual memory
// - freeing file descriptors (of any kind, plain fd, socket fd, whatever)
// - destroying child processes or threads
}
private:
Singleton()
{
}
// Forbid copies and assignment
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
};
You can have locking mechanisms also, to prevent concurrent instantiation from multiple threads (will need a static mutex of course!). But deletion is left to the (OS specific) process context here.
Usually you don't need to care about deletion of singleton classes, and how their acquired resources are released, because this is all handled by the OS when a process dies.
Anyway there might be use cases, when you want to have your singleton classes some backup points on program crash situations. Most C++ crt implementations support calling destructors of statically allocated instances, but you should take care not to have ordered dependencies for any of those destructors.
getInstance and delteInstance should be static, so they can only work with static members of the class. The static members don't get destroyed with the instance.
If your code is multithreaded, the code is not safe. There's no way to make sure there's no pointer to the instance held in some running context.
I have the following code:
MyClass.h:
static MyMutex instanceMutex;
static MyClass* getInstance();
static void deleteInstance();
MyClass.c:
MyMutex MyClass::instanceMutex;
MyClass* MyClass::getInstance()
{
if (theInstance == 0)
{
instanceMutex.acquire();
if (theInstance == 0)
{
theInstance = new MyClass();
}
instanceMutex.release();
}
return theInstance;
}
void MyClass::deleteInstance()
{
if (theInstance != 0)
{
instanceMutex.acquire();
if (theInstance != 0)
{
theInstance->finalize();
delete theInstance;
theInstance = 0;
}
instanceMutex.release();
}
return;
}
I have 2 questions on this:
Is the above code correct and safe?
After I call 'delete theInstance' in MyClass::deleteInstance(), I then call
theInstance = 0;
instanceMutex.release();
But if the instance is deleted than how is that even possible? isn't the memory of the class gone?
If it's a singleton - it is defined to have exactly one instance - if you delete it - this drops to 0
So it seems you should not support delete at all
Here be a problem:
if (theInstance == 0) // <- Some other thread might see a non-null theInstance
{ // before the constructor below returns
instanceMutex.acquire();
if (theInstance == 0)
{
theInstance = new MyClass(); // <- This might set theInstance to something
// before the constructor returns.
}
instanceMutex.release();
}
You may want to implement some sort of reference counting system (like using shared_ptr) and initializing it in a similar manner, though taking care to ensure that its instance pointer is not set before the initialization completes.
If you are feeling adventurous, you could also try:
if (theInstance == 0)
{
instanceMutex.acquire();
if (theInstance == 0)
{
MyClass * volatile ptr = new MyClass();
__FuglyCompilerSpecificFenceHintThatMightNotActuallyDoAnything();
theInstance = ptr; // <- Much hilarity may ensue if this write is not atomic.
}
instanceMutex.release();
}
This might fix it, and it might not. In the second case, it depends on how your compiler handles volatile, and weather or not pointer-sized writes are atomic.
In one project we inherited from some external company I've seen a whole nightmare class of errors caused by someone deleting the singleton. Perhaps in your rare case deleting the singleton doesn't have any side effects for the whole application, as you can be sure there is no instance of this singleton at use, but, generally, it's an excellent example of bad design. Someone could learn from your example and it would be a bad - even harmful - lesson. In case you need to clean up something in the singleton when the application exit, use the pattern ith returning reference to the singleton, like in example:
#include <iostream>
using namespace std;
class singleton {
private:
singleton() {
cout << "construktor\n";
}
~singleton() {
cout << "destructor\n";
}
public:
static singleton &getInstance() {
static singleton instance;
cout << "instance\n";
return instance;
}
void fun() {
cout << "fun\n";
}
};
int main() {
cout << "one\n";
singleton &s = singleton::getInstance();
cout << "two\n";
s.fun();
return 0;
}
I prefer to implement singletons in C++ in the following manner:
class Singleton
{
public:
static Singleton& instance()
{
static Singleton theInstance;
return theInstance;
}
~Singleton()
{
// Free resources that live outside the processes life cycle here,
// if these won't automatically be released when the occupying process
// dies (is killed)!
// Examples you don't have to care of usually are:
// - freeing virtual memory
// - freeing file descriptors (of any kind, plain fd, socket fd, whatever)
// - destroying child processes or threads
}
private:
Singleton()
{
}
// Forbid copies and assignment
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
};
You can have locking mechanisms also, to prevent concurrent instantiation from multiple threads (will need a static mutex of course!). But deletion is left to the (OS specific) process context here.
Usually you don't need to care about deletion of singleton classes, and how their acquired resources are released, because this is all handled by the OS when a process dies.
Anyway there might be use cases, when you want to have your singleton classes some backup points on program crash situations. Most C++ crt implementations support calling destructors of statically allocated instances, but you should take care not to have ordered dependencies for any of those destructors.
getInstance and delteInstance should be static, so they can only work with static members of the class. The static members don't get destroyed with the instance.
If your code is multithreaded, the code is not safe. There's no way to make sure there's no pointer to the instance held in some running context.
I have the following code:
MyClass.h:
static MyMutex instanceMutex;
static MyClass* getInstance();
static void deleteInstance();
MyClass.c:
MyMutex MyClass::instanceMutex;
MyClass* MyClass::getInstance()
{
if (theInstance == 0)
{
instanceMutex.acquire();
if (theInstance == 0)
{
theInstance = new MyClass();
}
instanceMutex.release();
}
return theInstance;
}
void MyClass::deleteInstance()
{
if (theInstance != 0)
{
instanceMutex.acquire();
if (theInstance != 0)
{
theInstance->finalize();
delete theInstance;
theInstance = 0;
}
instanceMutex.release();
}
return;
}
I have 2 questions on this:
Is the above code correct and safe?
After I call 'delete theInstance' in MyClass::deleteInstance(), I then call
theInstance = 0;
instanceMutex.release();
But if the instance is deleted than how is that even possible? isn't the memory of the class gone?
If it's a singleton - it is defined to have exactly one instance - if you delete it - this drops to 0
So it seems you should not support delete at all
Here be a problem:
if (theInstance == 0) // <- Some other thread might see a non-null theInstance
{ // before the constructor below returns
instanceMutex.acquire();
if (theInstance == 0)
{
theInstance = new MyClass(); // <- This might set theInstance to something
// before the constructor returns.
}
instanceMutex.release();
}
You may want to implement some sort of reference counting system (like using shared_ptr) and initializing it in a similar manner, though taking care to ensure that its instance pointer is not set before the initialization completes.
If you are feeling adventurous, you could also try:
if (theInstance == 0)
{
instanceMutex.acquire();
if (theInstance == 0)
{
MyClass * volatile ptr = new MyClass();
__FuglyCompilerSpecificFenceHintThatMightNotActuallyDoAnything();
theInstance = ptr; // <- Much hilarity may ensue if this write is not atomic.
}
instanceMutex.release();
}
This might fix it, and it might not. In the second case, it depends on how your compiler handles volatile, and weather or not pointer-sized writes are atomic.
In one project we inherited from some external company I've seen a whole nightmare class of errors caused by someone deleting the singleton. Perhaps in your rare case deleting the singleton doesn't have any side effects for the whole application, as you can be sure there is no instance of this singleton at use, but, generally, it's an excellent example of bad design. Someone could learn from your example and it would be a bad - even harmful - lesson. In case you need to clean up something in the singleton when the application exit, use the pattern ith returning reference to the singleton, like in example:
#include <iostream>
using namespace std;
class singleton {
private:
singleton() {
cout << "construktor\n";
}
~singleton() {
cout << "destructor\n";
}
public:
static singleton &getInstance() {
static singleton instance;
cout << "instance\n";
return instance;
}
void fun() {
cout << "fun\n";
}
};
int main() {
cout << "one\n";
singleton &s = singleton::getInstance();
cout << "two\n";
s.fun();
return 0;
}
I prefer to implement singletons in C++ in the following manner:
class Singleton
{
public:
static Singleton& instance()
{
static Singleton theInstance;
return theInstance;
}
~Singleton()
{
// Free resources that live outside the processes life cycle here,
// if these won't automatically be released when the occupying process
// dies (is killed)!
// Examples you don't have to care of usually are:
// - freeing virtual memory
// - freeing file descriptors (of any kind, plain fd, socket fd, whatever)
// - destroying child processes or threads
}
private:
Singleton()
{
}
// Forbid copies and assignment
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
};
You can have locking mechanisms also, to prevent concurrent instantiation from multiple threads (will need a static mutex of course!). But deletion is left to the (OS specific) process context here.
Usually you don't need to care about deletion of singleton classes, and how their acquired resources are released, because this is all handled by the OS when a process dies.
Anyway there might be use cases, when you want to have your singleton classes some backup points on program crash situations. Most C++ crt implementations support calling destructors of statically allocated instances, but you should take care not to have ordered dependencies for any of those destructors.
getInstance and delteInstance should be static, so they can only work with static members of the class. The static members don't get destroyed with the instance.
If your code is multithreaded, the code is not safe. There's no way to make sure there's no pointer to the instance held in some running context.
The usual pattern for a singleton class is something like
static Foo &getInst()
{
static Foo *inst = NULL;
if(inst == NULL)
inst = new Foo(...);
return *inst;
}
However, it's my understanding that this solution is not thread-safe, since 1) Foo's constructor might be called more than once (which may or may not matter) and 2) inst may not be fully constructed before it is returned to a different thread.
One solution is to wrap a mutex around the whole method, but then I'm paying for synchronization overhead long after I actually need it. An alternative is something like
static Foo &getInst()
{
static Foo *inst = NULL;
if(inst == NULL)
{
pthread_mutex_lock(&mutex);
if(inst == NULL)
inst = new Foo(...);
pthread_mutex_unlock(&mutex);
}
return *inst;
}
Is this the right way to do it, or are there any pitfalls I should be aware of? For instance, are there any static initialization order problems that might occur, i.e. is inst always guaranteed to be NULL the first time getInst is called?
If you are using C++11, here is a right way to do this:
Foo& getInst()
{
static Foo inst(...);
return inst;
}
According to new standard there is no need to care about this problem any more. Object initialization will be made only by one thread, other threads will wait till it complete.
Or you can use std::call_once. (more info here)
Your solution is called 'double checked locking' and the way you've written it is not threadsafe.
This Meyers/Alexandrescu paper explains why - but that paper is also widely misunderstood. It started the 'double checked locking is unsafe in C++' meme - but its actual conclusion is that double checked locking in C++ can be implemented safely, it just requires the use of memory barriers in a non-obvious place.
The paper contains pseudocode demonstrating how to use memory barriers to safely implement the DLCP, so it shouldn't be difficult for you to correct your implementation.
Herb Sutter talks about the double-checked locking in CppCon 2014.
Below is the code I implemented in C++11 based on that:
class Foo {
public:
static Foo* Instance();
private:
Foo() {}
static atomic<Foo*> pinstance;
static mutex m_;
};
atomic<Foo*> Foo::pinstance { nullptr };
std::mutex Foo::m_;
Foo* Foo::Instance() {
if(pinstance == nullptr) {
lock_guard<mutex> lock(m_);
if(pinstance == nullptr) {
pinstance = new Foo();
}
}
return pinstance;
}
you can also check complete program here: http://ideone.com/olvK13
Use pthread_once, which is guaranteed that the initialization function is run once atomically.
(On Mac OS X it uses a spin lock. Don't know the implementation of other platforms.)
TTBOMK, the only guaranteed thread-safe way to do this without locking would be to initialize all your singletons before you ever start a thread.
Your alternative is called "double-checked locking".
There could exist multi-threaded memory models in which it works, but POSIX does not guarantee one
ACE singleton implementation uses double-checked locking pattern for thread safety, you can refer to it if you like.
You can find source code here.
Does TLS work here? https://en.wikipedia.org/wiki/Thread-local_storage#C_and_C++
For example,
static _thread Foo *inst = NULL;
static Foo &getInst()
{
if(inst == NULL)
inst = new Foo(...);
return *inst;
}
But we also need a way to delete it explicitly, like
static void deleteInst() {
if (!inst) {
return;
}
delete inst;
inst = NULL;
}
The solution is not thread safe because the statement
inst = new Foo();
can be broken down into two statements by compiler:
Statement1: inst = malloc(sizeof(Foo));
Statement2: inst->Foo();
Suppose that after execution of statement 1 by one thread context switch occurs. And 2nd thread also executes the getInstance() method. Then the 2nd thread will find that the 'inst' pointer is not null. So 2nd thread will return pointer to an uninitialized object as constructor has not yet been called by the 1st thread.