国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 網站 > 建站經驗 > 正文

asp.net中C++單例實現、問題分析

2019-11-02 14:46:05
字體:
來源:轉載
供稿:網友

   方案一

 代碼如下   class QMManager
{
public:
    static QMManager &instance()
    {
        static QMManager instance_;
        return instance_;
    }
}

  這是最簡單的版本,在單線程下(或者是C++0X下)是沒任何問題的,但在多線程下就不行了,因為static QMManager instance_;這句話不是線程安全的。

  在局部作用域下的靜態變量在編譯時,編譯器會創建一個附加變量標識靜態變量是否被初始化,會被編譯器變成像下面這樣(偽代碼):

 代碼如下   static QMManager &instance()
{
    static bool constructed = false;
    static uninitialized QMManager instance_;
    if (!constructed) {
        constructed = true;
        new(&s) QMManager; //construct it
    }
    return instance_;
}

  這里有競爭條件,兩個線程同時調用instance()時,一個線程運行到if語句進入后還沒設constructed值,此時切換到另一線程,constructed值還是false,同樣進入到if語句里初始化變量,兩個線程都執行了這個單例類的初始化,就不再是單例了。

  方案二

  一個解決方法是加鎖:

 代碼如下   static QMManager &instance()
{
    Lock(); //鎖自己實現
    static QMManager instance_;
    UnLock();
    return instance_;
}

  但這樣每次調用instance()都要加鎖解鎖,代價略大。

  方案三

  那再改變一下,把內部靜態實例變成類的靜態成員,在外部初始化,也就是在include了文件,main函數執行前就初始化這個實例,就不會有線程重入問題了:

 代碼如下   class QMManager
{
protected:
    static QMManager instance_;
    QMManager();
    ~QMManager(){};
public:
    static QMManager *instance()
    {
        return &instance_;
    }
    void do_something();
};
QMManager QMManager::instance_; //外部初始化

  這被稱為餓漢模式,程序一加載就初始化,不管有沒有調用到。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 榕江县| 雅江县| 武功县| 侯马市| 全州县| 广河县| 屯昌县| 清水河县| 丰都县| 上杭县| 八宿县| 手游| 郑州市| 郁南县| 冷水江市| 娄烦县| 大洼县| 新绛县| 读书| 龙州县| 佳木斯市| 砀山县| 台北县| 邢台市| 大关县| 乐平市| 阿巴嘎旗| 资阳市| 芦溪县| 都昌县| 扬州市| 安丘市| 老河口市| 华蓥市| 沽源县| 论坛| 宁波市| 宜昌市| 金阳县| 吉木乃县| 临湘市|