C++單例模式(懶漢和餓漢)與線程安全


1. 餓漢模式

#include<iostream>


class singleton
{
private:
    static singleton* p;
    singleton(){}
public:
    static singleton* getInstance()
    {
        return p;
    } 
};

singleton* singleton::p = new singleton();

int main()
{
    singleton* p = singleton::getInstance();
    singleton* p2=  singleton::getInstance();
    std::cout << p << std::endl;
    std::cout << p << std::endl;
}

這是一個線程安全的實現方法,因為singleton::p在進入main函數之前就由單線程方式實例化,這也就是餓漢模式。相比之下懶漢模式就是第一次使用到類實例的時候才創建。

2. 懶漢模式

class singleton
{
private:
    static singleton* p;
    singleton(){}
public:
    static singleton* getInstance()
    {
        if(p == NULL)
        {
            p = new singleton();
            std::cout << "once" << std::endl;
        }
        else  std::cout << "not once" << std::endl;
        return p;
    } 
};

singleton* singleton::p = NULL;

3. 懶漢的線程安全問題

在多線程中,可能有多個線程同時判斷p==NULL為真,所以需要加鎖。

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

pthread_mutex_t singleton::mutex = PTHREAD_MUTEX_INITIALIZER;
singleton* singleton::p = NULL;

因為加鎖是一個耗時的操作,其實只有在第一次創建實例的時候需要加鎖,所以可以做一個優化:

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

pthread_mutex_t singleton::mutex = PTHREAD_MUTEX_INITIALIZER;
singleton* singleton::p = NULL;

 

參考鏈接:https://blog.csdn.net/hj605635529/article/details/70172842


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM