C
Capstar
Hi NG,
I was reading about Singletons on devX.
http://gethelp.devx.com/techtips/cpp_pro/10min/10min0200.asp
This is their class:
class Singleton
{
public:
static Singleton* Instance();
protected:
Singleton();
Singleton(const Singleton&);
Singleton& operator= (const Singleton&);
private:
static Singleton* pinstance;
};
This is their Instance() implementation:
Singleton* Singleton::Instance ()
{
if (pinstance == 0) // is it the first call?
{
pinstance = new Singleton; // create sole instance
}
return pinstance; // address of sole instance
}
And later they give an optimised singlethreaded version:
Singleton* Singleton::Instance ()
{
static Singleton inst;
return &inst;
}
They say the first one is threadsafe because new is threadsafe, and
second isn't threid safe.
I think the second isn't threadsafe because the constructor can be
executed by multiple threids simultainiously, which is not possible in
the first version.
But I don't believe the first one is thread safe because the OS can
interrupt this thread right after the "if (pinstance == 0)" check, end
resume an other thread, which might be doing the same.
So if this second thread does the test it still sees that pinstance
equals 0, and makes a new Singleton. But when the first thread is
resumed, it will also make a new Singleton because it still assumes that
pinstance equals 0. So pinstance is replaced by the new Singleton, and
the pointer to the previous one is overwritten, resulting in at least a
memory leak.
Is this correct, or am I missing something?
Mark
I was reading about Singletons on devX.
http://gethelp.devx.com/techtips/cpp_pro/10min/10min0200.asp
This is their class:
class Singleton
{
public:
static Singleton* Instance();
protected:
Singleton();
Singleton(const Singleton&);
Singleton& operator= (const Singleton&);
private:
static Singleton* pinstance;
};
This is their Instance() implementation:
Singleton* Singleton::Instance ()
{
if (pinstance == 0) // is it the first call?
{
pinstance = new Singleton; // create sole instance
}
return pinstance; // address of sole instance
}
And later they give an optimised singlethreaded version:
Singleton* Singleton::Instance ()
{
static Singleton inst;
return &inst;
}
They say the first one is threadsafe because new is threadsafe, and
second isn't threid safe.
I think the second isn't threadsafe because the constructor can be
executed by multiple threids simultainiously, which is not possible in
the first version.
But I don't believe the first one is thread safe because the OS can
interrupt this thread right after the "if (pinstance == 0)" check, end
resume an other thread, which might be doing the same.
So if this second thread does the test it still sees that pinstance
equals 0, and makes a new Singleton. But when the first thread is
resumed, it will also make a new Singleton because it still assumes that
pinstance equals 0. So pinstance is replaced by the new Singleton, and
the pointer to the previous one is overwritten, resulting in at least a
memory leak.
Is this correct, or am I missing something?
Mark