Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Is this Singleton class thread-safe?

Reply
Thread Tools

Is this Singleton class thread-safe?

 
 
Angus
Guest
Posts: n/a
 
      11-14-2007
Hello

I have written a singleton class like this:

//---------------------------------------------------------------------------
// Instance
//---------------------------------------------------------------------------
template <typename T>
T * CSingleton<T>::Instance(
) throw()
{
static T inst;
return &inst;
}

Is this thread safe? Could two threads (with cpu context switching)
possibly create more than one instance of the class passed as a
template? Is this possible? If it is I presume I must lock using
mutex or some mechanism before line - static T inst; and just after
it?

Angus

 
Reply With Quote
 
 
 
 
DJ
Guest
Posts: n/a
 
      11-14-2007
Angus napisał(a):
> Hello
>
> I have written a singleton class like this:
>
> //---------------------------------------------------------------------------
> // Instance
> //---------------------------------------------------------------------------
> template <typename T>
> T * CSingleton<T>::Instance(
> ) throw()
> {
> static T inst;
> return &inst;
> }
>
> Is this thread safe? Could two threads (with cpu context switching)
> possibly create more than one instance of the class passed as a
> template? Is this possible? If it is I presume I must lock using
> mutex or some mechanism before line - static T inst; and just after
> it?


It is not thread safe and you must lock it, however mutex lock might
give performace penalty - depends on yours app. There is something
called double-checking locking - google for that - it's well known and
described problem
 
Reply With Quote
 
 
 
 
Pete Becker
Guest
Posts: n/a
 
      11-14-2007
On 2007-11-14 12:35:27 -0500, Angus <(E-Mail Removed)> said:

> Hello
>
> I have written a singleton class like this:
>
> //---------------------------------------------------------------------------
> // Instance
> //---------------------------------------------------------------------------
> template <typename T>
> T * CSingleton<T>::Instance(
> ) throw()
> {
> static T inst;
> return &inst;
> }
>
> Is this thread safe?


The language definition doesn't say, because it doesn't deal with
threads. Check the documentation for your compiler.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

 
Reply With Quote
 
Gianni Mariani
Guest
Posts: n/a
 
      11-14-2007
DJ wrote:
> Angus napisał(a):
>> Hello
>>
>> I have written a singleton class like this:
>>
>> //---------------------------------------------------------------------------
>>
>> // Instance
>> //---------------------------------------------------------------------------
>>
>> template <typename T>
>> T * CSingleton<T>::Instance(
>> ) throw()
>> {
>> static T inst;
>> return &inst;
>> }
>>
>> Is this thread safe? Could two threads (with cpu context switching)
>> possibly create more than one instance of the class passed as a
>> template? Is this possible? If it is I presume I must lock using
>> mutex or some mechanism before line - static T inst; and just after
>> it?

>
> It is not thread safe and you must lock it, however mutex lock might
> give performace penalty - depends on yours app. There is something
> called double-checking locking - google for that - it's well known and
> described problem



Some compilers do make sure it's thread safe (see G++ past V4).

DCL (double checked locking) is not considered a good thing because it
does not work on all machines - see past articles on
comp.programing.threads.
 
Reply With Quote
 
DJ
Guest
Posts: n/a
 
      11-14-2007
Gianni Mariani napisał(a):
> DJ wrote:
>
>> Angus napisał(a):
>>
>>> Hello
>>>
>>> I have written a singleton class like this:
>>>
>>> //---------------------------------------------------------------------------
>>>
>>> // Instance
>>> //---------------------------------------------------------------------------
>>>
>>> template <typename T>
>>> T * CSingleton<T>::Instance(
>>> ) throw()
>>> {
>>> static T inst;
>>> return &inst;
>>> }
>>>
>>> Is this thread safe? Could two threads (with cpu context switching)
>>> possibly create more than one instance of the class passed as a
>>> template? Is this possible? If it is I presume I must lock using
>>> mutex or some mechanism before line - static T inst; and just after
>>> it?

>>
>>
>> It is not thread safe and you must lock it, however mutex lock might
>> give performace penalty - depends on yours app. There is something
>> called double-checking locking - google for that - it's well known and
>> described problem

>
>
>
> Some compilers do make sure it's thread safe (see G++ past V4).


I am just thinking if you call ::Instace before threads are created in
the app you should be fine as the static object must be created,
shoudn't you ?
>
> DCL (double checked locking) is not considered a good thing because it
> does not work on all machines - see past articles on
> comp.programing.threads.


true.
 
Reply With Quote
 
Gianni Mariani
Guest
Posts: n/a
 
      11-14-2007
DJ wrote:
....
> I am just thinking if you call ::Instace before threads are created in
> the app you should be fine as the static object must be created,
> shoudn't you ?


Yes.

>>
>> DCL (double checked locking) is not considered a good thing because it
>> does not work on all machines - see past articles on
>> comp.programing.threads.

>
> true.

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      11-15-2007
On Nov 14, 6:35 pm, Angus <(E-Mail Removed)> wrote:
> I have written a singleton class like this:


> //---------------------------------------------------------------------------
> // Instance
> //---------------------------------------------------------------------------
> template <typename T>
> T * CSingleton<T>::Instance(
> ) throw()
> {
> static T inst;
> return &inst;
> }


> Is this thread safe?


Maybe. You've cut the documentation which states its
requirements, so there's no way to tell.

> Could two threads (with cpu context switching) possibly create
> more than one instance of the class passed as a template? Is
> this possible?


Possibly. It depends on whether two threads have a right to do
this or not.

If you want to allow multiple threads to call Instance without
external locking, you'll probably have to take some precautions
internally.

> If it is I presume I must lock using mutex or some mechanism
> before line - static T inst; and just after it?


There are other solutions, depending on the context:

-- You could just document that the user must externally
synchronize calls to Instance. If the user needs external
synchronization to use the returned object anyway, this is
perfectly acceptable, and doubtlessly the simplest solution.

-- If you don't need to support multithreading before main is
called, something like:

T* Singleton<T>:urInstance = Singleton<T>::instance() ;

Singleton<T>*
Singleton<T>::instance()
{
return ourInstance == NULL
? new T
: ourInstance ;
}

can be used. This works if (and only if) instance() is
called at least once before threading starts; the
initializer of ourInstance guarantees that it will be called
at least once before main() is entered (in practice, if not
necessarily formally).

This is what I tend to do in generic solutions, or when T is
mainly a read-only object. (Note that this has the
additional advantage that the instance is never destructed,
so you don't run into order of destructor problems either.)

-- If the user absolutly needs external synchronization to use
the object, you can provide it for him, by returning a smart
pointer which reference counts, and whose last instance
unlocks, and grab the lock before starting. Something like:

pthread_mutex_t ourLock = PTHREAD_MUTEX_INITIALIZER ;

struct Unlocker
{
void operator()() {
pthread_mutex_unlock( &ourLock ) ;
}
} ;

boost::shared_ptr< T >
Singleton::instance()
{
pthread_mutex_lock( &ourLock ) ;
static T* theOneAndOnly = NULL ;
if ( theOneAndOnly == NULL ) {
theOneAndOnly = new Singleton ;
}
return boost::shared_ptr< T >( theOneAndOnly,
Unlocker() ) ;
}

Once again, the only lock you've acquired is one that the
user needed anyway.

(I don't think that this solution is appropriate for generic
code, but it seems a nice idea for some special cases.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34
 
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