Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

safe way to get a singleton instance from multithreads

Method 1

DataCenter* DataCenter::getInstance()
{
    static DataCenter instance;
    return &instance;    
}

Method 2

DataCenter* DataCenter::getInstance()
{
    if (!m_instanceFlag)
    {
        m_instance = new DataCenter();
        m_instanceFlag = true;
    }    
    return m_instance;      
}

I am working on a multi threaded programming and DataCenter will be accessed by more than one thread. I used to have method 2 to get the instance of DataCenter and it worked fine. But I noted that I need to guard the singleton instance from being called by multi threads.

My question is first do I really need to guard the singleton instance? or does OS do this for me? Second questions is that, is the first method a right way to get the singleton instance?

Thanks in advance...

like image 771
user800799 Avatar asked Jul 08 '11 05:07

user800799


1 Answers

1.You do need to guard it and even if you don't, of course, OS wouldn't do it for you. Use following code for thread-safety:

DataCenter* DataCenter::getInstance()
{
    MutexLocker locker(DataCenter::m_mutex);
    if(!m_instanceFlag)
    {
        m_instance = new DataCenter();
        m_instanceFlag = true;
    }
    return m_instance;
}

Edit:

Where MutexLocker is something like this:

class MutexLocker
{
    pthread_mutex_t &mutex;
    public:
    MutexLocker(pthread_mutex_t &mutex):mutex(mutex)
    {
        if(pthread_mutex_lock(&this->mutex)!=0)
            throw std::runtime_error("mutex locking filed");
    }
    ~MutexLocker(void)
    {
        if(pthread_mutex_unlock(&this->mutex)!=0)
            throw std::runtime_error("mutex unlocking filed");
    }
}

2.First method looks ok, but not thread-safe.

like image 140
Mihran Hovsepyan Avatar answered Sep 20 '22 02:09

Mihran Hovsepyan