Static allocation in a static function & thread safety

P

paolo.brandoli

Hello all,

Suppose that I have the following class "a" that returns a pointer to
a single instance of itself.

class a
{
public:
static a* getSingleInstance()
{
static a;
return &a;
}
};

The code is not thread safe, because several thread could call
getSingleInstance at the same time and the construction of a is not
guaranteed to be thread safe.

But if I add the following class "b", which call
a::getSingleInstance() in its constructor:

class b
{
public:
b()
{
a::getSingleInstance();
}
}

....and I add a static instance of b in some cpp file, like this:
static b;

this would still create the class "a" in the desidered order in case
it is needed by other static objects, but it would also create it in
case no other code require it. This would create the class before
main() starts and has the possibility to spawn other threads.

a::getSingleInstance() should be thread-safe from the second time it
is called, because the flag that controls the creation of the single
instance "a" doesn't need to be modified. I'm I right?

Would this make a::getSingleInstance() thread safe (supposing that
other static objects don't create any thread during their
construction)?

Any idea that would improve this?

Thanks in advance,
Paolo
 
G

Gianni Mariani

Hello all,

Suppose that I have the following class "a" that returns a pointer to
a single instance of itself.

class a
{
public:
static a* getSingleInstance()
{
static a;
return &a;
}
};

The code is not thread safe, because several thread could call
getSingleInstance at the same time and the construction of a is not
guaranteed to be thread safe.

The current C++ standard says nothing about threads. However, threads
are very topical in the next revision of the standard so let's go with
that ...

Local static object creation is thread safe with GCC and in my opinion
is the only way to read the standard. (note that this GCC feature is
broken on solaris.) The standard requires that the "a" object above is
created exactly once, any compiler that says it supports threads must
enforce the standard and so must make static object creation thread safe.
But if I add the following class "b", which call
a::getSingleInstance() in its constructor:

class b
{
public:
b()
{
a::getSingleInstance();
}
}

...and I add a static instance of b in some cpp file, like this:
static b;

this would still create the class "a" in the desidered order in case
it is needed by other static objects, but it would also create it in
case no other code require it. This would create the class before
main() starts and has the possibility to spawn other threads.

Starting multiple threads before main() is bad mojo precisely because
you can't be sure when all static objects are initialized.
a::getSingleInstance() should be thread-safe from the second time it
is called, because the flag that controls the creation of the single
instance "a" doesn't need to be modified. I'm I right?

Would this make a::getSingleInstance() thread safe (supposing that
other static objects don't create any thread during their
construction)?

Any idea that would improve this?

Use GCC ? File bugs with your compiler supplier ?
 
V

Victor Bazarov

[.. attempt to solve the problem of static initialisation in a multithreaded program ..]
this would still create the class "a" in the desidered order in case
it is needed by other static objects, but it would also create it in
case no other code require it. This would create the class before
main() starts and has the possibility to spawn other threads.

Why do you limit the possibility to "spawm other threads" to _after_
'main' has started?

BTW, initialisation of local static objects has been discussed not
once already, perhaps you should begin by reading the archives about
it so you don't repeat others' mistakes?... Just a thought.

V
 
A

arun.darra

Hello all,

Suppose that I have the following class "a" that returns a pointer to
a single instance of itself.

class a
{
public:
static a* getSingleInstance()
{
static a;
return &a;
}

};

The code is not thread safe, because several thread could call
getSingleInstance at the same time and the construction of a is not
guaranteed to be thread safe.

But if I add the following class "b", which call
a::getSingleInstance() in its constructor:

class b
{
public:
b()
{
a::getSingleInstance();
}

}

...and I add a static instance of b in some cpp file, like this:
static b;

this would still create the class "a" in the desidered order in case
it is needed by other static objects, but it would also create it in
case no other code require it. This would create the class before
main() starts and has the possibility to spawn other threads.

a::getSingleInstance() should be thread-safe from the second time it
is called, because the flag that controls the creation of the single
instance "a" doesn't need to be modified. I'm I right?

Would this make a::getSingleInstance() thread safe (supposing that
other static objects don't create any thread during their
construction)?

Any idea that would improve this?

Thanks in advance,
Paolo


If you want to add thread safty to a static getInstance method which
is responsible for creating a single instance of the class, you can
alter it as mentiong below and use the "double-checked locking"
mechanish.

class a
{
private:
static a *p;
public:
static a* getInstance()
{
if(p == NULL)
{
pthread_mutex_lock(&mutex);
if(p == NULL)
{
p = new a;
}
pthread_mutex_unlock(&mutex);
}
return p;
}
}
};

This will help u create a thread safe static getInstance method,
this technique is generally used for making the singleton pattern
thread safe.
 
C

Chris Thomasson

Hello all,

Suppose that I have the following class "a" that returns a pointer to
a single instance of itself. [...]
Would this make a::getSingleInstance() thread safe (supposing that
other static objects don't create any thread during their
construction)?

Any idea that would improve this?
[...]
If you want to add thread safty to a static getInstance method which
is responsible for creating a single instance of the class, you can
alter it as mentiong below and use the "double-checked locking"
mechanish. [...]
This will help u create a thread safe static getInstance method,
this technique is generally used for making the singleton pattern
thread safe.

Your example is simply infested with race-conditions! You have absolutely no
method in your code that addresses compiler and hardware reordering. For the
hardware reordering, you need a data-dependant load memory barrier after the
initial load, and a release memory barrier before the final store. For the
compiler reordering you need to read your documentation. I would advise that
you use assembly language to accomplish this task. Here is some more
detailed notes:

http://groups.google.com/group/comp.programming.threads/msg/ccb69ac2f850f453
 
C

Chris Thomasson

Here is some basic dcl pseudo-code that MUST be executed in the precise
given order:


1: static T *g_ptr = 0; // set before thread creation


T* instance() {

2: T* l_ptr = atomic_loadptr(&g_ptr);
3: membar #LoadLoad; // needed for alpha cpu's
4: if (! l_ptr) {
5: lock();
6: l_ptr = g_ptr;
7: if (! l_ptr) {
8: l_ptr = new T;
9: membar #LoadStore | #StoreStore;
10: atomic_storeptr(&g_ptr, l_ptr);
}
11: unlock();
}
12: return l_ptr;

}


http://groups.google.com/group/comp.programming.threads/browse_frm/thread/29ea516c5581240e
(read the entire thread...)
 

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

Similar Threads


Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top