Singleton Pattern

K

Keshav

HI,
I would like to know whetehr this is the right way to implement
thread safe singleton.
Generally we do locking and all at Instance method, Can we get rid of
these problems if we create instance while defining pInstance
variable.
Would it create any problem?


//CODE SNIPPET
class Sing
{
public:
static Sing* Instance();

protected:
Sing(){}
~Sing(){}

private:
Sing(const Sing&);
Sing& operator= (const Sing&);

static Sing* pinstance;
};

Sing* Sing::pinstance = Instance(); // Please NOTE THIS.
pInstance is initialized at definition.

Sing* Sing::Instance ()
{
if (pinstance == 0)
pinstance = new Sing;

return pinstance;

}


Thanks
K2
 
A

AnonMail2005

HI,
  I would like to know whetehr this is the right way to implement
thread safe singleton.
Generally we do locking and all at Instance method, Can we get rid of
these problems if we create instance while defining pInstance
variable.
Would it create any problem?

//CODE SNIPPET
class Sing
{
public:
        static Sing* Instance();

protected:
  Sing(){}
  ~Sing(){}

private:
        Sing(const Sing&);
        Sing& operator= (const Sing&);

        static Sing* pinstance;

};

Sing* Sing::pinstance = Instance();      // Please NOTE THIS.
pInstance is initialized at definition.

Sing* Sing::Instance ()
{
        if (pinstance == 0)
                pinstance = new Sing;

        return pinstance;

}

Thanks
K2

I assume your code post is actually the .h and the .cpp file.

You could initialize pinstance as you did if you make pinstance a non-
pointer.

But then you need to consider two issues:
1. You are creating this object even if it is never used.
2. If another singleton uses this singleton, you run into order of
initialization
issues. There is no guarentee that the singleton that is needed is
created before
the one that needs it if there are defined in separate compilation
units.

By creating the objects on demand, you don't have these issues.

HTH
 
J

joshuamaurice

HI,
I would like to know whetehr this is the right way to implement
thread safe singleton.
Generally we do locking and all at Instance method, Can we get rid of
these problems if we create instance while defining pInstance
variable.
Would it create any problem?
[snip]

There are 3 issues when creating a singleton in C++ that you have to
worry about:
- static initialization order fiasco (see the C++ FAQ)
- static de-initialization order fiasco (see the C++ FAQ)
- thread-safety (see any standard piece on thread safety in C++. I
strongly suggest
http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
as one of the best papers on the topic.)

If you can guarantee that no other global (or namespace) object will
use your singleton, then you can ignore static initialization order
problems and static de-initialization order problems. (This is not
something you can usually safely assumption. This is bad style to
assume this as it is fragile. Someone somewhere else can break your
code with touching your code at all. I will thus ignore this
possibility here.)

Your options are "eager-initialized initialized-on-demand singleton"
or "lazy-initialized initialized-on-demand singleton". There are
several implementations for each, depending on the threading primitive
you want to use.

An example implementation of "eager-initialized initialized-on-demand
singleton" (left as an exercise to determine which parts go in the
header and cpp). (Note that access to the singleton itself may require
a mutex. This just guarantees a single thread-safe construction.)

class singleton_t {};

singleton_t & getSingleton()
{ static singleton_t * x = 0;
if ( ! x)
x = new singleton_t;
return *x;
}

/* Eager initialize the singleton to ensure it's created before main,
and thus before there are multiple threads. If threads are created
before main, then it's impossible to do this safely in C++03.*/
namespace
{ struct EagerInitialize { EagerInitialize() { getSingleton(); } };
EagerInitialize instEagerInit;
}


An example implementation of "lazy-initialized initialized-on-demand
singleton" (left as an exercise to determine which parts go in the
header and cpp). (Note that it contains eager-initialization
initialization-on-demand of the guarding mutex.) (Note that access to
the singleton itself may require a mutex. This just guarantees a
single thread-safe construction.)

//from threading library
class mutex {};
class guard { public: guard(mutex& ); ~guard(); };

mutex & getSingletonMutex()
{ static mutex * x = 0;
if ( ! x)
x = new mutex;
return *x;
}

/* Eager initialize mutex to ensure it's created before main, and thus
before there are multiple threads. If threads are created before main,
then it's impossible to do this safely in C++03.*/
namespace
{ struct EagerInitialize { EagerInitialize() { getSingletonMutex
(); } };
EagerInitialize instEagerInit;
}

class singleton_t {};

singleton_t & getSingleton()
{ guard g(getSingletonMutex());
static singleton_t * x = 0;
if ( ! x)
x = new singleton_t;
return *x;
}


Other implementations are possible with memory barriers or other
threading primitives, but those are the simple ones using the simplest
and most portable threading primitive, mutexes.
 
J

James Kanze

I would like to know whetehr this is the right way to
implement thread safe singleton.

There is no "right" way. There are a number of different
solutions, appropriate in different cases. However...
Generally we do locking and all at Instance method, Can we get
rid of these problems if we create instance while defining
pInstance variable.

Locking each access is the "most correct" method.
Would it create any problem?

Only if you start a thread from a static constructor which uses
the singleton. I'd consider that bad practice, however, and in
practice, I use this solution most of the time.
//CODE SNIPPET
class Sing
{
public:
static Sing* Instance();

private:
Sing(const Sing&);
Sing& operator= (const Sing&);
static Sing* pinstance;
};
Sing* Sing::pinstance = Instance(); // Please NOTE THIS.
pInstance is initialized at definition.

Actually, it's initialized twice. First, it's zero initialized
before any actual code runs, then it is initialized with the
actual object during dynamic initialization.
Sing* Sing::Instance ()
{
if (pinstance == 0)
pinstance = new Sing;
return pinstance;
}

As I said, this is what I do most of the time. It has two
possible disadvantages: if you start a thread from the
constructor of another static object, you risk a race condition,
and if you never need the instance, you'll construct it anyway.
If neither of these are a consideration in your code, it's
probably the simplest solution.
 
J

James Kanze

On Apr 19, 9:07 am, Keshav <[email protected]> wrote:

[...]
I assume your code post is actually the .h and the .cpp file.

Or the entire project is just one big .cc file:).
You could initialize pinstance as you did if you make
pinstance a non-pointer.

I'm not sure I follow. His solution requires pInstance to be a
pointer.
But then you need to consider two issues:
1. You are creating this object even if it is never used.

That's a possible consideration. (Most of the time, I suspect
that it doesn't matter.)
2. If another singleton uses this singleton, you run into
order of initialization issues. There is no guarentee that
the singleton that is needed is created before the one that
needs it if there are defined in separate compilation units.
By creating the objects on demand, you don't have these
issues.

He is creating the object on demand. He's just forcing a demand
during dynamic initialization.
 
J

James Kanze

I would like to know whetehr this is the right way to
implement thread safe singleton. Generally we do locking
and all at Instance method, Can we get rid of these problems
if we create instance while defining pInstance variable.
Would it create any problem?

There are 3 issues when creating a singleton in C++ that you
have to worry about:
- static initialization order fiasco (see the C++ FAQ)
- static de-initialization order fiasco (see the C++ FAQ)
- thread-safety (see any standard piece on thread safety in C++. I
strongly suggesthttp://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
as one of the best papers on the topic.)
If you can guarantee that no other global (or namespace)
object will use your singleton, then you can ignore static
initialization order problems and static de-initialization
order problems. (This is not something you can usually safely
assumption. This is bad style to assume this as it is fragile.
Someone somewhere else can break your code with touching your
code at all. I will thus ignore this possibility here.)

Whether you can safely assume it depends on the "scope" (in the
general sense, not strictly in the language sense) of the
singleton. If the "singleton" is used only within a single
component, just making it a variable with static lifetime is
likely the preferred solution (although it does depend on the
component).
Your options are "eager-initialized initialized-on-demand
singleton" or "lazy-initialized initialized-on-demand
singleton". There are several implementations for each,
depending on the threading primitive you want to use.
An example implementation of "eager-initialized
initialized-on-demand singleton" (left as an exercise to
determine which parts go in the header and cpp). (Note that
access to the singleton itself may require a mutex. This just
guarantees a single thread-safe construction.)
class singleton_t {};
singleton_t & getSingleton()
{ static singleton_t * x = 0;
if ( ! x)
x = new singleton_t;
return *x;
}

How is that "eager"? It looks like lazy initialization to me.
/* Eager initialize the singleton to ensure it's created
before main, and thus before there are multiple threads. If
threads are created before main, then it's impossible to do
this safely in C++03.*/
namespace
{ struct EagerInitialize { EagerInitialize() { getSingleton(); } };
EagerInitialize instEagerInit;
}

That's fundamentally the same thing he's doing, except that I've
never seen anyone bother with the extra class. The two
"classical" solutions are usinge the results of instance to
initialize the pointer, and using some other "artificial"
variable, e.g.:

namespace {
bool dummyForInitialization = (Singleton::instance(), true) ;
}
An example implementation of "lazy-initialized
initialized-on-demand singleton" (left as an exercise to
determine which parts go in the header and cpp). (Note that it
contains eager-initialization initialization-on-demand of the
guarding mutex.) (Note that access to the singleton itself may
require a mutex. This just guarantees a single thread-safe
construction.)
//from threading library
class mutex {};
class guard { public: guard(mutex& ); ~guard(); };
mutex & getSingletonMutex()
{ static mutex * x = 0;
if ( ! x)
x = new mutex;
return *x;

}
/* Eager initialize mutex to ensure it's created before main,
and thus before there are multiple threads. If threads are
created before main, then it's impossible to do this safely in
C++03.*/
namespace
{ struct EagerInitialize { EagerInitialize() { getSingletonMutex
(); } };
EagerInitialize instEagerInit;
}
class singleton_t {};
singleton_t & getSingleton()
{ guard g(getSingletonMutex());
static singleton_t * x = 0;
if ( ! x)
x = new singleton_t;
return *x;
}

How does this ensure anything that his code doesn't? It still
fails if a thread which uses the singleton is started from the
constructor of a static object.

Under Unix, I frequently use a statically initialize
pthread_mutex_t for this sort of thing; as far as I know,
Windows doesn't have anything similar. Otherwise, you have to
ensure that at least one master mutex is created before
threading starts---if all threads are created by the same C++
threading library, the obvious solution is to use lazy
initialization to create the master mutex in the primitive which
creates the threads. (If all threads are created by primitives
in the library, obviously, when the first call to such a
primitive occurs, there are no other threads.)

Generally, if lazy initialization is used, the variable
controling the singleton will be local to the instance class,
e.g. either:

Singleton&
Singleton::instance()
{
ScopedLock l( mutex ) ;
static Singleton theOneAndOnly ;
return theOneAndOnly ;
}

or (more often, in my experience):

Singleton&
Singleton::instance()
{
ScopedLock l( mutex ) ;
static Singleton* theOneAndOnly = NULL ;
if ( theOneAndOnly == NULL ) {
theOneAndOnly = new Singleton ;
}
return *theOneAndOnly ;
}

(The first calls the destructor on the singleton object, with
the risk of order of destruction issues. The second never
destroys the singleton object.)

Of course, there's still the problem of constructing the mutex.
 
J

joshuamaurice

How is that "eager"?  It looks like lazy initialization to me. See my EagerInitialize class.

It's eager in that it's initialized in static's dynamic
initialization, before main is started.
That's fundamentally the same thing he's doing, except that I've
never seen anyone bother with the extra class.

Indeed. I dislike having a static pointer in the class though. Someone
may mistakenly use it as the authoritative version of the singleton,
when in fact it's just there to ensure initialization before main. I'd
move the pointer out of the class to (unnamed) namespace scope in a
cpp file and give it a better name, a name like yours, such as
dummyToForceInitBeforeMain.
The two
"classical" solutions are usinge the results of instance to
initialize the pointer, and using some other "artificial"
variable, e.g.:

    namespace {
    bool dummyForInitialization = (Singleton::instance(), true) ;
    }

No difference between this and my version, except this is simpler, so
I'll probably start using this myself.
How does this ensure anything that his code doesn't?

It doesn't. I never said his code was wrong. It does however have lazy
thread-safe initialization, whereas my first example and the OP's
example are eager initialization.
It still
fails if a thread which uses the singleton is started from the
constructor of a static object.

I did specifically note this restriction of my solution several
times.
Under Unix, I frequently use a statically initialize
pthread_mutex_t for this sort of thing; as far as I know,
Windows doesn't have anything similar.  Otherwise, you have to
ensure that at least one master mutex is created before
threading starts---if all threads are created by the same C++
threading library, the obvious solution is to use lazy
initialization to create the master mutex in the primitive which
creates the threads.  (If all threads are created by primitives
in the library, obviously, when the first call to such a
primitive occurs, there are no other threads.)

Generally, if lazy initialization is used, the variable
controling the singleton will be local to the instance class,
e.g. either:

    Singleton&
    Singleton::instance()
    {
        ScopedLock          l( mutex ) ;
        static Singleton    theOneAndOnly ;
        return theOneAndOnly ;
    }

or (more often, in my experience):

    Singleton&
    Singleton::instance()
    {
        ScopedLock          l( mutex ) ;
        static Singleton*   theOneAndOnly = NULL ;
        if ( theOneAndOnly == NULL ) {
            theOneAndOnly = new Singleton ;
        }
        return *theOneAndOnly ;
    }

Indeed. Some platforms require runtime initialization of mutexes,
-1- so you either program to a particular platform where this isn't a
restriction (Not always possible),
-2- you make a conscious design choice that there will be no threads
during dynamic initialization (Not always possible),
-3- or you have access to the single point of thread creation (Not
always possible).

In my company we have external users of our libraries, so 3 is not an
option. Users have direct access to whatever threading library they
want. Also, in my company, we try to support basically every server
platform there is, making 1 not an option. Thus a portable library
writer is left with 2 and making a big explicit note about this in the
interface doc. In my limited experience, the restriction of no threads
before main (or at least threads which only do trivial things before
main) is an acceptable restriction.
(The first calls the destructor on the singleton object, with
the risk of order of destruction issues. The second never
destroys the singleton object.)

Indeed. I'll let the C++ FAQ handle that one. Suffice to say, don't
destroy when the OS will reclaim resources, i.e. don't destroy if the
process dying makes the leak irrelevant.
Of course, there's still the problem of constructing the mutex.

Which I addressed by making the mutex itself initialized-on-demand
eager-initialized.
 
J

James Kanze

It's eager in that it's initialized in static's dynamic
initialization, before main is started.
Indeed. I dislike having a static pointer in the class though.

So put it in anonymous namespace in the implementation file. It
doesn't matter. Except that if you're trying to implement a
generic Singleton; templates can't use anonymous namespace
unless your compiler supports export.
Someone may mistakenly use it as the authoritative version of
the singleton, when in fact it's just there to ensure
initialization before main. I'd move the pointer out of the
class to (unnamed) namespace scope in a cpp file and give it a
better name, a name like yours, such as
dummyToForceInitBeforeMain.

There was a difference when I used that name. In his code (and
in mine), the pointer really was a pointer to the single
existing instance; in my own code, its called ourInstance ("our"
being the prefix I use for static members, or anything shared
between all instances). Before I created the template, it
usually was in anonymous namespace; in the generic
implementation, however, it's a static member variable. But the
purpose of the pointer isn't (only) to ensure initialization
before main; it is the pointer to the single instance, and it is
what the function Singleton::instance() returns.

This technique does depend on a subtle point---the fact that the
pointer is guaranteed to be null before the dynamic
initialization occurs. This is something I've often counted on
in C++, and seems natural to me, but I can understand some
programmers being bothered by the fact that given:
Singleton* Singleton::eek:urSingleton = Singleton::instance() ;
, there is code which counts of the fact that ourSingleton is
actually first initialized with a null pointer. And if that's
the case, I can easily see spending an extra, boolean variable
(e.g. dummyToForceInitBeforeMain), in addition to the pointer,
in order to make the issue clear, e.g.:
Singleton* Singleton::eek:urSingleton = NULL ;
bool dummyToForceInitBeforeMain = (Singleton::instance(), true ) ;
It's certainly clearer. (Using the pointer, as I and the
original poster do, is cleverer. One could easily say, too
clever.)
No difference between this and my version, except this is
simpler, so I'll probably start using this myself.

Yes. What I was complaining about in your version was the
unnecessary extra complexity. For the rest, it's pretty much a
standard solution.
It doesn't. I never said his code was wrong. It does however
have lazy thread-safe initialization, whereas my first example
and the OP's example are eager initialization.

Yes, but I was concerned about getting the mutex. Somehow,
you've got to get at least one mutex constructed before
threading starts; otherwise, you're going to encounter race
conditions constructing the mutex. All the above really does is
defer the problem from the singleton to the getSingletonMutex
function.
I did specifically note this restriction of my solution
several
times.
Indeed. Some platforms require runtime initialization of
mutexes,
-1- so you either program to a particular platform where this
isn't a restriction (Not always possible),

It is in my case:). But yes, not everyone can ignore Windows.
-2- you make a conscious design choice that there will be no
threads during dynamic initialization (Not always possible),

You *can* usually impose that there be no threads using your
singletons before main. Usually, not always.
-3- or you have access to the single point of thread creation
(Not always possible).

Again, you *can* usually impose that any thread which uses your
components be started by your threading library. Again,
usually, not always.
In my company we have external users of our libraries, so 3 is
not an option. Users have direct access to whatever threading
library they want.

You're providing a set of components. You can impose
restrictions on code using those components---in fact, you
almost always have to. In our application, for example, we use
lazy initialization for the master mutex. It will fail if a
thread that uses our components is started before main. But
that's a documented restriction for our components; it doesn't
mean that the third party libraries we link against can't start
threads, and at least one, the Sybase library, does. But of
course, Sybase doesn't use our components.
Also, in my company, we try to support basically every server
platform there is, making 1 not an option. Thus a portable
library writer is left with 2 and making a big explicit note
about this in the interface doc. In my limited experience, the
restriction of no threads before main (or at least threads
which only do trivial things before main) is an acceptable
restriction.

As I said above, the restriction is "no threads which use your
components". In our case, the Sybase threads are far from
trivial (I think). But as third party software, they obviously
don't use our components.
Indeed. I'll let the C++ FAQ handle that one. Suffice to say,
don't destroy when the OS will reclaim resources, i.e. don't
destroy if the process dying makes the leak irrelevant.

For memory, that's usually the case. On the other hand, if the
singleton creates a temporary file...
Which I addressed by making the mutex itself
initialized-on-demand eager-initialized.

Yes. That was my point: you need eager initialization
somewhere.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top