Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Writing Singleton Classes

Reply
Thread Tools

Writing Singleton Classes

 
 
cppaddict
Guest
Posts: n/a
 
      05-13-2004
Hi,

In this tutorial on singleton class in C++
(http://gethelp.devx.com/techtips/cpp.../10min0200.asp) the
author gives two implementations of a simple singleton class, claiming
that only the first is safe for multi-threaded appliactions. I want
to know why this so.

The class is as follows:

class Singleton
{
public:
static Singleton* Instance();
protected:
Singleton();
Singleton(const Singleton&);
Singleton& operator= (const Singleton&);
private:
static Singleton* pinstance;
};

The first implementation is:

Singleton* Singleton:instance = 0;// initialize pointer
Singleton* Singleton::Instance ()
{
if (pinstance == 0) // is it the first call?
{
pinstance = new Singleton; // create sole instance
}
return pinstance; // address of sole instance
}
Singleton::Singleton()
{
//... perform necessary instance initializations
}

The second implementation makes a small change to the constructor:

Singleton* Singleton::Instance ()
{
static Singleton inst;
return &inst;
}

The author notes that the second implementation is optimized for
single-threaded applications. Why would it not also work for
multi-threaded applications?

Thanks,
cpp

 
Reply With Quote
 
 
 
 
red floyd
Guest
Posts: n/a
 
      05-13-2004
cppaddict wrote:

> Hi,
>
> In this tutorial on singleton class in C++
> (http://gethelp.devx.com/techtips/cpp.../10min0200.asp) the
> author gives two implementations of a simple singleton class, claiming
> that only the first is safe for multi-threaded appliactions. I want
> to know why this so.
>
> The class is as follows:
>
> class Singleton
> {
> public:
> static Singleton* Instance();
> protected:
> Singleton();
> Singleton(const Singleton&);
> Singleton& operator= (const Singleton&);
> private:
> static Singleton* pinstance;
> };


Looks to me like the *first* instance isn't thread safe, but the second is!

> The first implementation is:
>
> Singleton* Singleton:instance = 0;// initialize pointer
> Singleton* Singleton::Instance ()
> {
> if (pinstance == 0) // is it the first call?
> {

What happens if a context switch occurs right here? After the if
statemnt, but before the new?
> pinstance = new Singleton; // create sole instance
> }
> return pinstance; // address of sole instance
> }
> Singleton::Singleton()
> {
> //... perform necessary instance initializations
> }
>
> The second implementation makes a small change to the constructor:

Not a constructor, but the Singleton accessor.
>

As far as I can tell, this *is* thread safe.
> Singleton* Singleton::Instance ()
> {
> static Singleton inst;
> return &inst;
> }
>
> The author notes that the second implementation is optimized for
> single-threaded applications. Why would it not also work for
> multi-threaded applications?


I think the author is full of it, but that's just *MY* opinion... I
could be wrong.

 
Reply With Quote
 
 
 
 
Benoit Mathieu
Guest
Posts: n/a
 
      05-13-2004
cppaddict wrote:
> Hi,
>
> In this tutorial on singleton class in C++
> (http://gethelp.devx.com/techtips/cpp.../10min0200.asp) the
> author gives two implementations of a simple singleton class, claiming
> that only the first is safe for multi-threaded appliactions. I want
> to know why this so.
> ...


I found an answer here :
http://blogs.msdn.com/oldnewthing/ar.../08/85901.aspx

Now, the first implementation is also problematic, and has
exactely the same problem: initialisation must be protected
by a mutex or something...

Benoit
 
Reply With Quote
 
cppaddict
Guest
Posts: n/a
 
      05-13-2004

>Now, the first implementation is also problematic, and has
>exactely the same problem: initialisation must be protected
>by a mutex or something...
>
>Benoit


Thanks for the reference. That's very interesting....

What is a mutex though? After reading that article it seems that
Singletons are never thread safe.

Thanks,
cpp
 
Reply With Quote
 
Tim Clacy
Guest
Posts: n/a
 
      05-13-2004
cppaddict wrote:
> Hi,
>
> In this tutorial on singleton class in C++
> (http://gethelp.devx.com/techtips/cpp.../10min0200.asp) the
> author gives two implementations of a simple singleton class, claiming
> that only the first is safe for multi-threaded appliactions. I want
> to know why this so.


cppaddict,

The first implementation needs a slight change to be thread-safe:

Singleton* Singleton::Instance ()
{
// In the common case, simply return the existing instance (no
locking required)
//
if (pinstance != 0)
return pinstance;

// If there was no instance above, we need to lock now and
double-check whether
// another thread created an instance in between the check above and
now
//
Lock();
if (pinstance == 0)
pinstance = new Singleton;
Unlock();

return pinstance;
}

There are a dozen or so Singleton articles on CodeProject; the following is
very good and covers threading issues:

Singleton Pattern: A review and analysis of existing C++ implementations
http://www.codeproject.com/cpp/singleton.asp


Tim


 
Reply With Quote
 
Benoit Mathieu
Guest
Posts: n/a
 
      05-13-2004
> What is a mutex though? After reading that article it seems that
> Singletons are never thread safe.


Mutex means Mutual Exclusion (it's a mechanism that ensures
that at most one thread accesses a particular object at a
given time). See Tim Clacy's post: Lock() prevents other
threads from executing the sequence until Unlock() has been
called. Lock and Unlock can usually not be implemented with
high level standard instructions. It always involves some
machine specific instructions (disabling interruptions, ...)
but this is going to be very off-topic here and you will
have to switch to another group to get informations about
locking mechanisms.

Local static variables are not safe, but implementing a
Singleton with Tim Clacy's code is safe (provided that
Lock() and Unlock() are correct, of course) :

Lock();
if (pinstance == 0)
pinstance = new Singleton;
Unlock();

Benoit
 
Reply With Quote
 
Xenos
Guest
Posts: n/a
 
      05-13-2004

"red floyd" <(E-Mail Removed)> wrote in message
news:hgPoc.7978$(E-Mail Removed) ...
> As far as I can tell, this *is* thread safe.
> > Singleton* Singleton::Instance ()
> > {
> > static Singleton inst;
> > return &inst;
> > }
> >

No, its not. If the first thread is in the middle of construction, and get
preempted, the object is in an unknown state when the second thread attempts
access. This is safe from order dependencies during init., but not thread
safe. The opposite is true for the first form. It is thread-safe because
it is initialized before the application's main procedure runs and therefore
before the program can spawn any threads. It is not safe from order
dependencies if a staticly constructed object from a different file attempts
access to it during construction.



 
Reply With Quote
 
Xenos
Guest
Posts: n/a
 
      05-13-2004

"Xenos" <(E-Mail Removed)> wrote in message
news:c80l8r$(E-Mail Removed)...
>
> "red floyd" <(E-Mail Removed)> wrote in message
> news:hgPoc.7978$(E-Mail Removed) ...
> > As far as I can tell, this *is* thread safe.
> > > Singleton* Singleton::Instance ()
> > > {
> > > static Singleton inst;
> > > return &inst;
> > > }
> > >

> No, its not. If the first thread is in the middle of construction, and

get
> preempted, the object is in an unknown state when the second thread

attempts
> access. This is safe from order dependencies during init., but not thread
> safe. The opposite is true for the first form. It is thread-safe because
> it is initialized before the application's main procedure runs and

therefore
> before the program can spawn any threads. It is not safe from order
> dependencies if a staticly constructed object from a different file

attempts
> access to it during construction.
>
>
>


Looked at code to quick, the first is not thread-safe either. I thought it
was constructor at startup, not is not.



 
Reply With Quote
 
Xenos
Guest
Posts: n/a
 
      05-13-2004

"Xenos" <(E-Mail Removed)> wrote in message
news:c80ldi$(E-Mail Removed)...
> Looked at code to quick, the first is not thread-safe either. I thought

it
> was constructor at startup, not is not.


Geesh! Now I'm just typing to fast.

....constructed at strartup, but it is not!


 
Reply With Quote
 
DaKoadMunky
Guest
Posts: n/a
 
      05-13-2004
Neither of the solutions in the article originally referenced are thread safe.

In a threaded program both could lead to undesired behavior such as double
construction or premature access.

One of the respondents to this thread posted an example of the Double Checked
Locking idiom.

Apparently even that is problematic as discussed by Scott Meyers in the
document @ http://www.nwcpp.org/Downloads/2004/DCLP_notes.pdf

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Singleton methods without the singleton class Charles Oliver Nutter Ruby 4 03-22-2010 10:46 PM
Singleton object vs. enhancing singleton class Paul McMahon Ruby 3 06-09-2008 06:05 AM
Singleton Modules rather than Singleton Classes Trans Ruby 12 09-14-2007 06:45 AM
Singleton - Whether Cloneable overrides Singleton Proton Projects - Moin Java 4 03-27-2007 02:59 AM
Singleton classes and Singleton pattern Wilhelm Ruby 1 10-11-2006 01:08 PM



Advertisments