Writing a thread safe singleton has its difficulties. One of them is making sure that the dynamic creation of the inner singleton object is thread safe, while locking as few mutexes as possible.

Let’s first look at a naive Instance static member function:

MyClass* MyClass::Instance()
{
    if (!pInstance) {
        pInstance = new ....
    }
    return pInstance;
}

Obviously, it is not thread safe. Two threads can cause the instance to be created twice. A natural solution is just to use a mutex:

MyClass* MyClass::Instance()
{
    // Mutex is freed when the local lock object is destructed
    mutex lock("Mutex0");

    if (!pInstance) {
        pInstance = new ....
    }
    return pInstance;
}

Assuming that MyClass::Instance() is called very frequently, the last implementation will slow down the execution, since locking (especially a mutex) can be very very slow. However, locking is only needed for the instance’s creation, and not for every time we are trying to get the instance. Following is a very simple improvement:

MyClass* MyClass::Instance()
{
    if (!pInstance) {
        mutex lock("Mutex0");

        if (!pInstance) {
            pInstance = new ....
        }
    }
    return pInstance;
}

Every caller who enters the function after pInstance was allocated will not lock the mutex. Callers who enter the function before the instance was created are still synchronized with the mutex.

References

Posted by Ofer Kapota | |

1 Comment »

  1. There are issues with this:
    http://en.wikipedia.org/wiki/Double-checked_locking

    Specifically, compilers may optimize the pInstance in such a way that pInstance will point to a partially constructed object.

    Comment by EJ — November 21, 2007 @ 3:13 am

RSS feed for comments on this post. TrackBack URI

Leave a comment