I have the following class
class Singleton
{
private:
static Singleton *p_inst;
Singleton();
public:
static Singleton * instance()
In multi-threading that clause
if(!p_inst)
{
p_inst = new Singleton();
}
is actually 3 separate actions. You are getting the value of p_inst
, setting the value of p_inst
and writing the value of p_inst
. So get-set-write means that you need to put a lock around p_inst
otherwise you can have 2 threads which create a Singleton
value that each thread uses.
Here is how you can view the issue, assume that your Singleton
has a mutable field val
:
thread A -> p_inst is NULL
thread B -> p_inst is NULL
thread A -> set to Singleton (1)
thread B -> set to Singleton (2)
thread C -> p_inst is Singleton (2)
thread A -> set val to 4
thread B -> set val to 6
thread C -> get val (it's 6)
thread A -> get val (it's 4!!)
You see? There's 2 copies of a Singleton floating about, neither of which knows about the other. The third thread which checks on the Singleton
is only going to see the last assignment. But with locking, you can prevent multiple assignment and these types of problems.
You can eliminate all issues by simply allocating (any way you choose) such objects before multiple threads are started. This may not always be possible due to design constraints (using the singletons in statics, you NEED lazy allocation, etc.), but it is simple and gives you control of the creation sequence. Sometimes tracking down issues with regard to order and time of allocation of such objects is a hassle that you can easily avoid.
P.S. - I know that this doesn't directly answer your question, but it may be a practical solution to a real problem without complexity.
You will have to use a mutex and lock the pointer before assigning or reading it, making this a slow (and imo just plain terrible) design pattern.
For multithreaded construction, use static variable in an instance() function. Initialization of static variables is automatically protected by the compiler. Any other operations require explicit locking. Use mutexes.
class Singleton
{
private:
Singleton();
public:
static Singleton * instance()
{
static Singleton inst;
return &inst;
}
};
I will be brief: it depends on your compiler.
Now, you have to realize that you may not need this.
There are 2 ways to deal with this, that do not require any multithread awareness.
static
instance instead of dynamically allocate it. Safe and simple. May cause issue with initialization order if you need to access it from another static
variablemain
.Of course, the real question is: can't you just pass a reference to the object rather than creating a global variable ? It would make testing easier ;)
You should ask yourself what you mean by thread safety.
Does your singleton actually need thread safety?
If not, consider a thread-static approach
Do you want to guarantee that no two instances of the singleton ever get created?
If not, your above solution is probably fine, without any locking: you've got a race condition on construction - but you don't care since eventually only one will survive - however, you may have a resource leak unless you're careful, which may or may not be significant. (This is essentially a cache).
Do you want to guarantee that eventually only one instance remains?
Do you care about locking costs?
If not (which is quite common), you can just put a lock around it and be happy.
A singleton is a pattern that can address various problems - but what flavor of thread-safety is required has little to do with the singleton pattern itself and everything to do with what you want it for.