Confused about a thread-safe singleton example.

N

Noah Roberts

Mostly organization and personal preference. I'd rather keep the
"getInstance" as a static member of the relevant class, and I just
prefer to access it through a function rather than making it a public
static member of the class. There's no functional reason, though.


There are at least two functional reasons:

1. Protection against future instantiation of the type in question.

2. Protection against rewrite of the global reference.

With a singleton you can keep developers not up on the API from using it
incorrectly. You can keep them from instantiating a type that must
never be instantiated again. You can also keep them from attempting to
replace the variable through either simply blocking that access or
providing appropriate filters to do so.

The singleton is not a global variable. The singleton ENCAPSULATES a
global variable. More encapsulation is always good. You can always
crack open a singleton by exposing its creational interface. You can
change it's internal behavior such that it's actually a conglomeration
of many objects without any client knowing this. Hiding a global
variable is much more difficult.

Yet more interesting is a little pattern I found that I'm sure others
have as well, the use of pimpl to implement singleton. The object uses
the handle/body (pimpl) idiom but the impl is actually a singleton.
Clients who create instances of the class itself have no knowledge that
they're all working with the same 'object'. This is something you could
do, in theory, with global variables but ICK!

The problem with singleton is that people abuse it, as can be seen by
the fact that very few participating in this discussion seem to
understand its intended purpose: enforcing a creational policy.
 
J

jason.cipriani

No.

It's actually very hard to answer concretely here.  Objects with
static lifetime in class or namespace scope are constructed
before main is entered, so if threads aren't started until then,
you're OK.  Except that if getInstance is called before then,
you may have an order of initialization problem.  And the
guarantee of construction before main is entered doesn't apply
to dynamically linked objects (which aren't addressed by the
standard, but then, neither is multi-threading).

Thanks! Fortunately in my case things are simple, I don't have to deal
with dynamically linked objects, and I can guarantee that no threads
are started before main().

I have another question, on the subject of static initialization order
in general, not thread safety. Is it guaranteed that statics in a
given translation unit will be initialized before the first time a
function in that translation unit is called? E.g. if I have this:

static TheClass *ourInstance = new TheClass;

TheClass & TheClass::instance () {
return *ourInstance;
}

Even I call TheClass::instance() during static initialization of
another object that was initialized first, will simply calling that
function guarantee that ourInstance will be initialized in time?
My usual solution here is something like:

    namespace {
    TheClass* ourInstance = &TheClass::instance() ;
    }

    TheClass&
    TheClass::instance()
    {
        if ( ourInstance == NULL ) {
            ourInstance = new TheClass ;
            //  or
            static TheClass theOneAndOnly ;
            ourInstance = &theOneAndOnly ;
        }
        return *ourInstance ;
    }

The initializer for the static variable ensures that
TheClass::instance is called at least once before main is
entered, and once you've returned from a call to
TheClass::instance(), the function is thread safe without locks.


Because it's open to order of initialization issues.

I see, that does explain it. I guess it's only useful in limited
situations.


Thanks again,
Jason
 
J

jason.cipriani

There are at least two functional reasons:

1. Protection against future instantiation of the type in question.

2. Protection against rewrite of the global reference.

With a singleton you can keep developers not up on the API from using it
incorrectly.  You can keep them from instantiating a type that must
never be instantiated again.  You can also keep them from attempting to
replace the variable through either simply blocking that access or
providing appropriate filters to do so.

The singleton is not a global variable.  The singleton ENCAPSULATES a
global variable.  More encapsulation is always good.  You can always
crack open a singleton by exposing its creational interface.  You can
change it's internal behavior such that it's actually a conglomeration
of many objects without any client knowing this.  Hiding a global
variable is much more difficult.

Yet more interesting is a little pattern I found that I'm sure others
have as well, the use of pimpl to implement singleton.  The object uses
the handle/body (pimpl) idiom but the impl is actually a singleton.
Clients who create instances of the class itself have no knowledge that
they're all working with the same 'object'.  This is something you could
do, in theory, with global variables but ICK!

That is interesting, although I'm having trouble imagining a situation
I'd use it in.
The problem with singleton is that people abuse it, as can be seen by
the fact that very few participating in this discussion seem to
understand its intended purpose: enforcing a creational policy.

My use of it seems a little bit unusual... maybe there is a better
way. Basically I have something like this (although I've greatly
simplified):

=== begin example ===

// Some base class.
class ThingBase {
...
};

// Some default implementation of ThingBase.
class DefaultThing : public ThingBase {
public:
static DefaultThing * getInstance ();
private:
DefaultThing (...);
};

// And many other ThingBase derived classes exist.

// SomeClass uses a ThingBase:
class SomeClass {
public:

// This takes a ThingBase, but NULL can be specified to
// use the default implementation.
SomeClass (ThingBase *thing, ...)
: thing_(thing ? thing : DefaultThing::getInstance())
{
}

private:
ThingBase *thing_;
};

=== end example ===


Like I said, I simplified -- there are other ways to construct a
SomeClass with a default "thing" besides just passing NULL to a
constructor.

What I am trying to do here is avoid having to instantiate a new
DefaultThing in SomeClass if the default was to be used, because then
I would have to keep track of whether or not I actually did that, and
add some logic to delete "thing_" in ~SomeClass() if so. I do this
same thing in other places besides SomeClass, and using a single
instance of DefaultThing simplified things all around. The
implementation details of DefaultThing do make it safe to use a single
instance from everywhere, by the way.

I had also considered simply having a static DefaultThing instance in
SomeClass (and other static instances in other classes besides
SomeClass). It's not a problem to instantiate more than one
DefaultThing, the only requirement is a simple way to eliminate clean
up logic.

But... I was confused (and still am a little) about static
initialization order and wasn't sure if that was a good idea or not.
I'm trying to impose as little usage requirements as possible because
eventually other developers are going to have to work with this, and I
want to minimize the amount of slapping-people-around-when-they-don't-
read-my-documentation that I have to do -- assuming I'm still even
working on the project.

Thanks,
Jason
 
M

Maxim Yegorushkin

Globals do not offer any protection against further instantiation.  If
something must be unique then it should only be possible to create a
single variable of that type.  How are you going to offer that with an
unprotected variable, a comment saying, "Don't make any of these..."?

It looks like you are confusing types with variables. The ability to
create a variable of a particular type depends on that type only, not
whether there are variables of that type and whether those variables
are global or not.

Using abstract classes (interfaces) and global references you can
achieve the desired effect.
That method does not work.

[]

Here is a proof that it works. Example of a type you can't instantiate
and a global variable of that type:

// header.h begin
struct X
{
virtual void foo() = 0;
};
extern X& global_x;
// header.h end

// source.cc begin
#include "header.h"
namespace {
struct XImpl : X
{
void foo() {}
} x;
}
X& global_x = x;
// source.cc end
 
M

Maxim Yegorushkin

[]
Yet more interesting is a little pattern I found that I'm sure others
have as well, the use of pimpl to implement singleton.  The object uses
the handle/body (pimpl) idiom but the impl is actually a singleton.
Clients who create instances of the class itself have no knowledge that
they're all working with the same 'object'.  This is something you could
do, in theory, with global variables but ICK!

It is called monostate.
 
J

jason.cipriani

That is interesting, although I'm having trouble imagining a situation
I'd use it in.


My use of it seems a little bit unusual... maybe there is a better
way. Basically I have something like this (although I've greatly
simplified):

=== begin example ===

// Some base class.
class ThingBase {
  ...

};

// Some default implementation of ThingBase.
class DefaultThing : public ThingBase {
public:
  static DefaultThing * getInstance ();
private:
  DefaultThing (...);

};

// And many other ThingBase derived classes exist.

// SomeClass uses a ThingBase:
class SomeClass {
public:

  // This takes a ThingBase, but NULL can be specified to
  // use the default implementation.
  SomeClass (ThingBase *thing, ...)
    : thing_(thing ? thing : DefaultThing::getInstance())
  {
  }

private:
  ThingBase *thing_;

};

=== end example ===

Like I said, I simplified -- there are other ways to construct a
SomeClass with a default "thing" besides just passing NULL to a
constructor.

What I am trying to do here is avoid having to instantiate a new
DefaultThing in SomeClass if the default was to be used, because then
I would have to keep track of whether or not I actually did that, and
add some logic to delete "thing_" in ~SomeClass() if so. I do this
same thing in other places besides SomeClass, and using a single
instance of DefaultThing simplified things all around. The
implementation details of DefaultThing do make it safe to use a single
instance from everywhere, by the way.

I had also considered simply having a static DefaultThing instance in
SomeClass (and other static instances in other classes besides
SomeClass). It's not a problem to instantiate more than one
DefaultThing, the only requirement is a simple way to eliminate clean
up logic.

But... I was confused (and still am a little) about static
initialization order and wasn't sure if that was a good idea or not.
I'm trying to impose as little usage requirements as possible because
eventually other developers are going to have to work with this, and I
want to minimize the amount of slapping-people-around-when-they-don't-
read-my-documentation that I have to do -- assuming I'm still even
working on the project.


I guess something that makes my use of it questionable is that it
doesn't actually matter if more than one instance of DefaultThing
exist -- except in my application there really isn't (and won't be) a
reason to instantiate one explicitly (even though it's not a problem
to allow it).

I have a need for a global instance, but no need to enforce that the
global instance was the only one in existence, so I really only need
half of the singleton model. E.g., making the constructors public in
addition to a static getInstance() wouldn't cause any harm.

Jason
 
N

Noah Roberts

Maxim said:
It looks like you are confusing types with variables.

If you say so.

The ability to
create a variable of a particular type depends on that type only, not
whether there are variables of that type and whether those variables
are global or not.

Using abstract classes (interfaces) and global references you can
achieve the desired effect.
That method does not work.

[]

Here is a proof that it works. Example of a type you can't instantiate
and a global variable of that type:

// header.h begin
struct X
{
virtual void foo() = 0;
};
extern X& global_x;
// header.h end

// source.cc begin
#include "header.h"
namespace {
struct XImpl : X
{
void foo() {}
} x;
}
X& global_x = x;
// source.cc end

And look, you've just implemented a singleton. This isn't 'just' a global.
 
N

Noah Roberts

Maxim said:
[]
Yet more interesting is a little pattern I found that I'm sure others
have as well, the use of pimpl to implement singleton. The object uses
the handle/body (pimpl) idiom but the impl is actually a singleton.
Clients who create instances of the class itself have no knowledge that
they're all working with the same 'object'. This is something you could
do, in theory, with global variables but ICK!

It is called monostate.

It would appear to fit that pattern and just be a variation of
implementation.
 
N

Noah Roberts

I guess something that makes my use of it questionable is that it
doesn't actually matter if more than one instance of DefaultThing
exist -- except in my application there really isn't (and won't be) a
reason to instantiate one explicitly (even though it's not a problem
to allow it).

I have a need for a global instance, but no need to enforce that the
global instance was the only one in existence, so I really only need
half of the singleton model. E.g., making the constructors public in
addition to a static getInstance() wouldn't cause any harm.

Right, that seems appropriate with one caveat: default to private scope
and pull out when necessary.

If you're developing a library for others to use then sure, make the
constructor public and all that. If you're not then why bother?
Enforce singleton until you need to instantiate again. It's easy to
crack a singleton open if you're in control of it.

Some design consultants even recommend always keeping constructors
private and using factory methods for every type. This works in other
languages but not so much C++ since it would enforce heap allocation.
 
M

Maxim Yegorushkin

[]
Using abstract classes (interfaces) and global references you can
achieve the desired effect.
That method does not work.

Here is a proof that it works. Example of a type you can't instantiate
and a global variable of that type:
    // header.h begin
    struct X
    {
        virtual void foo() = 0;
    };
    extern X& global_x;
    // header.h end
    // source.cc begin
    #include "header.h"
    namespace {
    struct XImpl : X
    {
        void foo() {}
    } x;
    }
    X& global_x = x;
    // source.cc end

And look, you've just implemented a singleton.  This isn't 'just' a global.

A global variable by definition is a singleton, is it not?

Singleton is an idea that there is only one object of some thing. In C+
+ it can be represented as global object, as SomeThing::instance(),
same pimpl / monostate, and likely there are more ways of representing
this idea.

Singleton is undeniably a useful idea. My point is that representing
singletons as regular global objects looks to me more natural and
elegant than SomeThing::instance(). May be because C++ is considered a
multi-paradigm language and SomeThing::instance() looks coming from
the object-oriented paradigm of it, whereas global variables feel
natural when using C++ both as a procedural programming language and
OO-language: just a regular variable with a large scope.
 
J

James Kanze

I have another question, on the subject of static
initialization order in general, not thread safety. Is it
guaranteed that statics in a given translation unit will be
initialized before the first time a function in that
translation unit is called? E.g. if I have this:
static TheClass *ourInstance = new TheClass;
TheClass & TheClass::instance () {
  return *ourInstance;
}
Even I call TheClass::instance() during static initialization
of another object that was initialized first, will simply
calling that function guarantee that ourInstance will be
initialized in time?

NO. That's what we mean when we speak of the order of
initialization problem. That's why we have a pointer, which we
test for null, or we use a local static, or some other solution
in which the function constructs the first time it is called.
 
J

James Kanze

Alan said:
anon said:
(e-mail address removed) wrote:
[lots of cutting]
1. Don't use singletons.  Ever.  Pretty much all of the
value of the GoF Design Patterns book is negated by the
fact that they chose to legitimize Singleton as a design
pattern.  Singleton is just a fancy name for global
variable.  We should call it the Global Variable
(anti)Pattern.
greatly simplifies a lot of application code. And you are
correct, in this case it basically is, in fact, a global
variable.
Both of you are not correct. The singleton is not a global
variable.
TheClass* instance = NULL; TheClass * GetInstance() { if (
NULL == instance ) { instance = new TheClass; } return
instance; }
In this case, the instance is created when the function
GetInstance()  gets called the first time, while global
variables gets created before entering main()
That still has all the negative effects of a global
variable.  To name a few
= hidden dependencies in functions that use it
= persistent global state
- tight coupling between anything that uses it
Explain why these are problems.

Well, they are problems. Whether they're big problems, or just
minor ones, depends on the class. And of course, the
alternative solutions aren't necessarily without problems
either. So you make a trade off---for things like the command
line, configuration files, logging, etc.---I (and from what I've
seen, I'm far from alone) find that the costs involved in using
a singleton are far less than those involved in any of the
proposed alternatives. So singleton it is.
 Where are the *hidden* dependencies?

Come now... You call a function, and it changes global state.
Or doesn't---who knows?
If persistent global state is needed then why enforce a policy
that dictates you don't have persistent global state?  How are
you to remove coupling between objects that use each other?  Is
there some extra form of coupling you think exists here?

If the coupling is there, you can't remove it---if an object
uses configuration data, or the log, it depends on the
configuration data or the log. The argument is, I think, that
when these are global variables (or singletons), this coupling
isn't visible. Passing the configuration and the log to it
makes the dependency visible. Of course, it also makes for a
lot of extra work, and the people I've worked with have always
been able to understand that the semantics of configuration data
and logs are such that everything does implicitly depend on
them, so making the dependency more visible wasn't considered
worth the effort.

[...]
Who says?

More to the point: if there's only one instance of a type,
what's the point of deriving from that type?
Once again, this does not protect against the creation of
another variable of that type.

Nor does it handle order of initialization issues (but that is,
I admit, secondary to the consideration you mentionned).
 
J

James Kanze

[...]
Yet more interesting is a little pattern I found that I'm sure
others have as well, the use of pimpl to implement singleton.
 The object uses the handle/body (pimpl) idiom but the impl is
actually a singleton. Clients who create instances of the
class itself have no knowledge that they're all working with
the same 'object'.

That's interesting. That's the pattern I used before I read the
GoF. I adopted the GoF pattern because it seems worthwhile to
follow a commonly accepted model, but I'll have to admit that
having to constantly write those calls to instance() is
gradually getting on my nerves. On the other hand, the earlier
pattern (which I called the Module pattern, because the class in
fact acted like a module) does sort of create the impression
that you have several independent instances; sometimes, this is
even what you want (where the sharing is an implementation
detail, for example), but most of the time, it seems a little
like confuscation.

Lately, I've been toying with the idea of using the singleton
idiom for the (private) data, but making all of the functions
static. It's just an idea, though; I've not actually tried it
out to see how it works in practice.
 This is something you could do, in theory, with global
variables but ICK!
The problem with singleton is that people abuse it, as can be
seen by the fact that very few participating in this
discussion seem to understand its intended purpose: enforcing
a creational policy.

If all you've got is a hammer, everything looks like a nail.
The singleton is probably the easiest pattern to understand, so
some people just stop there, and use it for everything. It's
appropriate when it's appropriate, but only when it's
appropriate.
 
J

jason.cipriani

Maxim said:
Maxim Yegorushkin wrote:
1. Don't use singletons.  Ever.  Pretty much all of the value
of the GoF Design Patterns book is negated by the fact that
they chose to legitimize Singleton as a design pattern.
Singleton is just a fancy name for global variable.  We should
call it the Global Variable (anti)Pattern.
And there are valid reasons for using it.
What are those reasons?
Some things must be inherently unique in a process.
This is what global variables are for.
Globals do not offer any protection against further instantiation.  If
something must be unique then it should only be possible to create a
single variable of that type.  How are you going to offer that with an
unprotected variable, a comment saying, "Don't make any of these..."?
[]


Using abstract classes (interfaces) and global references you can
achieve the desired effect.
That method does not work.
[]
Here is a proof that it works. Example of a type you can't instantiate
and a global variable of that type:
    // header.h begin
    struct X
    {
        virtual void foo() = 0;
    };
    extern X& global_x;
    // header.h end
    // source.cc begin
    #include "header.h"
    namespace {
    struct XImpl : X
    {
        void foo() {}
    } x;
    }
    X& global_x = x;
    // source.cc end
And look, you've just implemented a singleton.  This isn't 'just' a global.

A global variable by definition is a singleton, is it not?

Nay, it is not. The one key part of the singleton model that a global
variable does not satisfy is limiting the number of instances of a
class to 1. For example:

class ArbitraryClass {
public:
ArbitraryClass ();
};

extern ArbitraryClass g_instance;

There is a global variable, it's an instance of ArbitraryClass.
However, ArbitraryClass is not a singleton. Since more than one
instance of ArbitraryClass can exist, it is *not* using the singleton
model.

It is true that in many cases, a global instance and an instance of a
singleton class can be accessed in similar ways, but that does not
make the two the same. There are other points to the singleton model
besides just a globally accessible instance.
Singleton is an idea that there is only one object of some thing. In C+
+ it can be represented as global object, as SomeThing::instance(),
same pimpl / monostate, and likely there are more ways of representing
this idea.

Yes, singleton is an idea that there is only one instance of some
thing. Storing an instance of some arbitrary class in a global
variable, however, does not enforce that, and does not follow the
singleton model.
Singleton is undeniably a useful idea. My point is that representing
singletons as regular global objects looks to me more natural and
elegant than SomeThing::instance().

The problem is that a global variable does not sufficiently represent
a singleton, as it does not enforce that only one instance of the
class exists.

The matter of it looking more natural is, of course, a personal
preference. The SomeThing::instance() interface to a singleton
instance is idiomatic and easily recognizable.
May be because C++ is considered a
multi-paradigm language and SomeThing::instance() looks coming from
the object-oriented paradigm of it, whereas global variables feel
natural when using C++ both as a procedural programming language and
OO-language: just a regular variable with a large scope.

Singleton classes are different than a regular variable with a large
scope. The purpose of the singleton model is to limit the number of
instances of a class to 1. You don't even need to use the
Class::getInstance() interface, you only need to ensure that only a
single instance of the class exists at any given time. A global
variable alone has no effect on this requirement.

If you wanted to access the class through a global variable rather
than a function call, you'd have to go out of your way to make that
happen; perhaps, for example, by sticking to idiomatic singleton
implementations and assigning the single instance to a global
variable. There is no reason to do that, though.

Jason
 
C

Chris M. Thomasson

I have a C++-specific question about thread-safe singleton instances.
There's a trivial example here:

http://www.bombaydigital.com/arenared/2005/10/25/1

That goes like this, very simple and straightforward:

static Mutex mutex;
static TheClass *instance;

static TheClass * getInstance () {
MutexLocker lock(mutex);
if (!instance)
instance = new TheClass();
return instance;
}

The example then goes on to talk about how double-check locking is
broken, etc. My question is pretty much this: Is C++ static
initialization thread-safe? If not, then how does the above example
safely use "mutex"? If so, then what is wrong with this:

static TheClass instance; // not a pointer

static TheClass * getInstance () {
return &instance; // it's correctly initialized?
}

The reason I ask is I almost never see it done like that, I always see
blog entries and articles that say the same thing "store instance in a
pointer, use a mutex to protect, and p.s. double-checked locking is
broken". It seems like doing it lock-free is made out to be a hard
problem, so *if* having a static instance works (but I don't know if
it does, that's my question), then why doesn't anybody ever suggest
it?

You can "easily" use `pthread_once()' and compiler specific directives to
construct a fairly "efficient" singleton pattern; something like this
pseudo-code:




namespace posix {

template<typename T>
class once {
__thread T* g_tls;
static T* g_obj;
static pthread_once_t g_once;


__cdecl void g_init() {
assert(! g_obj);
static T the_instance;
g_obj = &the_instance;
}


static T* instance() {
if (! g_tls) {
pthread_once(&g_once, g_init);
g_tls = g_obj;
assert(g_tls);
}
return g_tls;
}
};


template<typename T>
T* once<T>::g_obj = NULL;

template<typename T>
pthread_once_t once<T>::g_once = PTHREAD_ONCE_INIT;

} // namespace posix




There are some important rules to be followed for Meyers singleton objects
behavior wrt dtors:


1. Don't call ANY unknown code whatsoever!


2a. Don't even look at any singleton!!


2b. Don't call ANY _known_ code which might want to look at _any_
singleton!!


3. Accessing another singleton from the dtor is BAD!!!




;^(...
 
C

Chris M. Thomasson

[...]
There are some important rules to be followed for Meyers singleton objects
behavior wrt dtors:


1. Don't call ANY unknown code whatsoever!

Too harsh...


1. Refer to 2a/b and 3.


;^)
 
C

Chris M. Thomasson

[...]
namespace posix {

template<typename T>
class once {
__thread T* g_tls;
static T* g_obj;
static pthread_once_t g_once;


__cdecl void g_init() {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


should of course add static for this procedure in the pseudo-code somewhere:


static __cdecl void g_init() {
assert(! g_obj);
static T the_instance;
g_obj = &the_instance;
}


static T* instance() {
if (! g_tls) {
pthread_once(&g_once, g_init);
g_tls = g_obj;
assert(g_tls);
}
return g_tls;
}
};


template<typename T>
T* once<T>::g_obj = NULL;

template<typename T>
pthread_once_t once<T>::g_once = PTHREAD_ONCE_INIT;

} // namespace posix

[...]
 
A

anon

On Dec 3, 1:47 am, Alan Johnson <[email protected]> wrote:
[lots of cutting]
1. Don't use singletons. Ever. Pretty much all of the value of the GoF
Design Patterns book is negated by the fact that they chose to
legitimize Singleton as a design pattern. Singleton is just a fancy
name for global variable. We should call it the Global Variable
(anti)Pattern.
greatly simplifies a lot of application code. And you are correct, in
this case it basically is, in fact, a global variable.
Both of you are not correct. The singleton is not a global variable.

TheClass* instance = NULL;
TheClass * GetInstance()
{
if ( NULL == instance )
{
instance = new TheClass;
}
return instance;

}

In this case, the instance is created when the function GetInstance()
gets called the first time, while global variables gets created before
entering main()

Juts to pick nits, in my particular situation I'm instantiating the
object at global scope, so it is initialized before main(), not on
first demand:

static TheClass *instance = new TheClass();

TheClass * GetInstance () {
return instance;
}


That maybe not be the singleton. What prevents you from creating more
then one instance of TheClass class?

btw how is TheClass declared?
 
J

James Kanze

A global variable by definition is a singleton, is it not?

No. A singleton is a type, not a variable. What characterizes
a type as a singleton is that there can only be zero or one
instances of the type in a program. The restriction on the
number of instances is part of the abstraction of the type.
 

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

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top