Static allocation in a static function & thread safety

Discussion in 'C++' started by paolo.brandoli@gmail.com, Aug 23, 2007.

  1. Guest

    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
     
    , Aug 23, 2007
    #1
    1. Advertising

  2. wrote:
    > 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 ?
     
    Gianni Mariani, Aug 23, 2007
    #2
    1. Advertising

  3. wrote:
    > [.. 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Aug 23, 2007
    #3
  4. Guest

    On Aug 24, 1:35 am, wrote:
    > 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.
     
    , Aug 23, 2007
    #4
  5. <> wrote in message
    news:...
    > On Aug 24, 1:35 am, wrote:
    >> 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
     
    Chris Thomasson, Aug 23, 2007
    #5
  6. 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...)
     
    Chris Thomasson, Aug 23, 2007
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?V2ViTWF0cml4?=

    Static Functions and Thread Safety. How does it work?

    =?Utf-8?B?V2ViTWF0cml4?=, Mar 24, 2006, in forum: ASP .Net
    Replies:
    6
    Views:
    16,355
  2. Ken
    Replies:
    24
    Views:
    3,879
    Ben Bacarisse
    Nov 30, 2006
  3. Olumide
    Replies:
    6
    Views:
    587
    Ian Collins
    Oct 23, 2007
  4. Hicham Mouline
    Replies:
    5
    Views:
    2,385
    James Kanze
    Dec 19, 2008
  5. Eric Snow

    static statements and thread safety

    Eric Snow, Sep 22, 2011, in forum: Python
    Replies:
    0
    Views:
    181
    Eric Snow
    Sep 22, 2011
Loading...

Share This Page