• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            OnTheWay2012
            埋葬昨天的我,迎來(lái)重生的我!
            posts - 15,  comments - 89,  trackbacks - 0
            昨天寫(xiě)了一篇隨筆,里面提到了單例模式,本來(lái)沒(méi)有想多說(shuō)單例模式,可是有人回復(fù)說(shuō)讓我先看看線程安全再來(lái)談設(shè)計(jì)模式。
            今天閑來(lái)無(wú)事就隨便寫(xiě)了個(gè)線程安全的設(shè)計(jì)模式,具體代碼如下:
              1#include <iostream>
              2#include <vector>
              3#include <bitset>
              4#include <assert.h>
              5#include <Windows.h>
              6#include <process.h>
              7
              8using namespace std;
              9
             10class CSingleton
             11{
             12private:
             13    class CAssistForSingleton
             14    {
             15    private:
             16        CRITICAL_SECTION m_cs;
             17
             18    public:
             19        CAssistForSingleton()
             20        {
             21            InitializeCriticalSection(&m_cs);
             22        }

             23
             24        ~CAssistForSingleton()
             25        {
             26            DeleteCriticalSection(&m_cs);
             27        }

             28
             29    public:
             30        void Lock()
             31        {
             32            EnterCriticalSection(&m_cs);
             33        }

             34
             35        void UnLock()
             36        {
             37            LeaveCriticalSection(&m_cs);
             38        }

             39    }
            ;
             40
             41private:
             42    static CAssistForSingleton m_refSycObj;
             43    static CSingleton *m_pInstance;
             44
             45    static int m_nData;
             46
             47private:
             48    CSingleton()
             49    {
             50
             51    }

             52
             53public:
             54    static CSingleton *GetInstatnce()
             55    {
             56        m_refSycObj.Lock();
             57        if (NULL == m_pInstance)
             58        {
             59            m_pInstance = new CSingleton;
             60            cout<<"new CSingleton"<<endl;
             61        }

             62        m_refSycObj.UnLock();
             63
             64        return m_pInstance;
             65    }

             66
             67public:
             68    static int GetData() 
             69    {
             70        return m_nData;
             71    }

             72
             73    static void SetData(int nData)
             74    {
             75        m_refSycObj.Lock();
             76        m_nData = nData;
             77        m_refSycObj.UnLock();
             78    }

             79}
            ;
             80
             81CSingleton::CAssistForSingleton CSingleton::m_refSycObj = CSingleton::CAssistForSingleton();
             82CSingleton *CSingleton::m_pInstance = NULL;
             83int CSingleton::m_nData = 0;
             84
             85unsigned int WINAPI ThreadFun(void *)
             86{
             87    cout<<"Launcher Thread"<<endl;
             88    
             89    for(int i = 0 ; i < 99999999 ; i++)
             90    {
             91        CSingleton *pSingl = CSingleton::GetInstatnce();
             92        if (NULL != pSingl)
             93        {
             94            pSingl->SetData(i);
             95        }

             96
             97        Sleep(500);
             98    }

             99
            100    return 0;
            101}

            102
            103int main(int argv, char *argc[])
            104{
            105    uintptr_t HandleThread[10];
            106    unsigned int nThreadId = 0;
            107    for(int i = 0 ; i < 10 ; i++)
            108    {
            109        HandleThread[i] = _beginthreadex(NULL, 0, ThreadFun, NULL, 0&nThreadId);
            110    }

            111
            112    WaitForMultipleObjects(10, (const HANDLE *)HandleThread, TRUE, INFINITE);
            113
            114    return 0;
            115}

            116
            117

            以上就是我的實(shí)現(xiàn),有什么問(wèn)題歡迎批評(píng)指針。
            posted on 2010-05-21 09:52 OnTheWay 閱讀(5747) 評(píng)論(15)  編輯 收藏 引用 所屬分類: 軟件設(shè)計(jì)

            FeedBack:
            # re: 一種線程安全的單例模式實(shí)現(xiàn)方式
            2010-05-21 10:15 | 戰(zhàn)魂小筑
            1. 可以不用單件, 程序開(kāi)始時(shí)全局new出來(lái), 以后不用鎖,直接用就好.
            2. 既然全是靜態(tài)數(shù)據(jù), 還需要用Singleton呢?
            3. 用Interlock會(huì)更高效  回復(fù)  更多評(píng)論
              
            # re: 一種線程安全的單例模式實(shí)現(xiàn)方式
            2010-05-21 10:52 | GunsNRose
            之前看過(guò)一個(gè),建議將構(gòu)造弄成 私有的,生成實(shí)例由 GetInstatnce來(lái)做
            別人new是new不了的  回復(fù)  更多評(píng)論
              
            # re: 一種線程安全的單例模式實(shí)現(xiàn)方式
            2010-05-21 15:37 | OwnWaterloo
            依然不是線程安全的。  回復(fù)  更多評(píng)論
              
            # re: 一種線程安全的單例模式實(shí)現(xiàn)方式
            2010-05-21 21:02 | ccsdu2009
            去看看ZThread中的單件吧

            以前的話我會(huì)推薦loki的
            但是現(xiàn)在歸納絕那個(gè)太復(fù)雜了  回復(fù)  更多評(píng)論
              
            # re: 一種線程安全的單例模式實(shí)現(xiàn)方式[未登錄](méi)
            2010-05-22 07:17 | OnTheWay
            @OwnWaterloo
            您好,首先感謝您對(duì)本隨筆的關(guān)注。懇請(qǐng)您說(shuō)詳細(xì)一點(diǎn),我不太明白哪些地方還不是線程安全的。  回復(fù)  更多評(píng)論
              
            # re: 一種線程安全的單例模式實(shí)現(xiàn)方式
            2010-05-22 08:57 | OwnWaterloo
            @OnTheWay
            class S
            {
            S() { ... }
            ~S(); { ... }
            S(S const&);
            S& operator=(S const&S);

            public:
            static S& instance()
            {
            static S s;
            return s;
            }

            };

            你認(rèn)為C++(C++03)是否保證S::instance是線程安全的?
            如果是, 請(qǐng)說(shuō)明理由。
            如果C++不保證, 是否應(yīng)該將S::instance作成線程安全的?
              回復(fù)  更多評(píng)論
              
            # re: 一種線程安全的單例模式實(shí)現(xiàn)方式
            2010-05-22 09:00 | OwnWaterloo
            @OnTheWay
            再來(lái)一種:

            class S
            {
            // ctor, copy, dtor, assignment
            static S s_;
            public:
            S& instance() { return s_; }
            };

            S S::s_;

            同樣是上面的問(wèn)題。
              回復(fù)  更多評(píng)論
              
            # re: 一種線程安全的單例模式實(shí)現(xiàn)方式[未登錄](méi)
            2010-05-22 09:12 | OnTheWay
            @OwnWaterloo
            我覺(jué)得不是線程安全的,原因如下:
            在你給出的代碼中類S中的函數(shù)(雖然現(xiàn)在我還沒(méi)有想不出這種函數(shù))可能不是線程安全的。

            我的MSN是wwj_5_209@163.com,能否加我一下,我們討論一下。  回復(fù)  更多評(píng)論
              
            # re: 一種線程安全的單例模式實(shí)現(xiàn)方式
            2010-05-22 14:59 | 匿名
            @OwnWaterloo
            與博文中的不是一回事。  回復(fù)  更多評(píng)論
              
            # re: 一種線程安全的單例模式實(shí)現(xiàn)方式
            2010-05-22 19:08 | OwnWaterloo
            @OnTheWay
            注意兩種需要運(yùn)行時(shí)初始化的靜態(tài)對(duì)象, s和s_。
            前者的初始化時(shí)機(jī)C++有保證, 但不保證多線程安全。
            后者的初始化時(shí)機(jī)C++只保證同一翻譯單元內(nèi)中有順序。

            再看static CAssistForSingleton m_refSycObj;
            這就屬于第2種。

            下面的情況有發(fā)生的可能性:
            1. 另一翻譯單元的靜態(tài)對(duì)象先于m_refSycObj被初始化
            2. 在它初始化時(shí)訪問(wèn)了CSingleton *GetInstatnce()

            此時(shí)就訪問(wèn)了一個(gè)"未初始化"的臨界區(qū)。
            這已經(jīng)是bug。

            再有, 如果有下列情況:
            1. 一些先于m_refSycObj初始化的代碼開(kāi)啟了線程
            2. 多個(gè)線程在m_refSycObj初始化前訪問(wèn)CSingleton *GetInstatnce()

            一個(gè)未初始化的m_refSycObj根本不能用于同步。

            所以, 上面的第1個(gè)問(wèn)題: 這樣做不是多線程安全的。


            而靜態(tài)對(duì)象在構(gòu)造時(shí)啟動(dòng)線程的情況并不多, 所以并不一定需要將s_作成多線程安全。
            例如boost就是這樣, 要求在進(jìn)入main之前, 是不許有兩條以上的執(zhí)行路徑去訪問(wèn)。
            這就是第2個(gè)問(wèn)題。


            如果需要完全的多線程安全:
            1. 使用once_initial函數(shù)(pthread或者win6有提供)
            2. 使用"可以靜態(tài)初始化"的鎖, 比如pthread_mutex_t就可以
            或者自己使用一個(gè)spinlock也行。

            我沒(méi)有msn…… 用gmail的同名郵箱。
              回復(fù)  更多評(píng)論
              
            # re: 一種線程安全的單例模式實(shí)現(xiàn)方式
            2010-05-22 19:09 | OwnWaterloo
            @匿名
            知道什么叫"舉一反三"嗎?
              回復(fù)  更多評(píng)論
              
            # re: 一種線程安全的單例模式實(shí)現(xiàn)方式[未登錄](méi)
            2010-05-22 22:50 | ~
            個(gè)人一點(diǎn)隨想:我覺(jué)得應(yīng)該從實(shí)際應(yīng)用的邏輯上來(lái)進(jìn)行線程安全的分析,并根據(jù)現(xiàn)實(shí)情況的分析避免不必要的加解鎖操作。某些代碼只是一種理想化的東西。現(xiàn)實(shí)中有太多比SetData復(fù)雜的邏輯。而且也不一定需要加鎖。當(dāng)然從你這個(gè)代碼看,GetInstatnce當(dāng)然是正確的哈。  回復(fù)  更多評(píng)論
              
            # re: 一種線程安全的單例模式實(shí)現(xiàn)方式
            2010-05-27 00:02 | GunsNRose
            傻逼實(shí)現(xiàn)也好意思貼出來(lái)?丟人現(xiàn)眼  回復(fù)  更多評(píng)論
              
            # re: 一種線程安全的單例模式實(shí)現(xiàn)方式[未登錄](méi)
            2010-05-27 08:56 | cppexplore
            @OnTheWay
            c++里的線程安全單例應(yīng)該是典型的雙重檢測(cè).
            文中如此實(shí)現(xiàn)的話, 每次調(diào)用GetInstatnce都要涉及到加鎖操作, 估計(jì)沒(méi)人愿意調(diào)用.   回復(fù)  更多評(píng)論
              
            # re: 一種線程安全的單例模式實(shí)現(xiàn)方式
            2010-10-30 14:27 | 楊云召
            沒(méi)有用volatile,顯然不是線程安全的  回復(fù)  更多評(píng)論
              

            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理



            <2010年5月>
            2526272829301
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

            常用鏈接

            留言簿(4)

            隨筆分類

            隨筆檔案

            友情連接

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            国产精品久久久久久久久久影院| 伊人久久精品线影院| 久久综合亚洲欧美成人| 久久精品人人做人人爽电影蜜月| 久久99国产综合精品| 亚洲国产精品久久久久婷婷软件| 精品国产综合区久久久久久| 亚洲国产天堂久久久久久| 色偷偷偷久久伊人大杳蕉| 久久精品视频免费| 伊人久久成人成综合网222| 囯产精品久久久久久久久蜜桃| 99re这里只有精品热久久| 国产综合成人久久大片91| 久久久久亚洲AV无码专区首JN | 国内精品伊人久久久久av一坑 | 久久人搡人人玩人妻精品首页| 久久精品国产欧美日韩99热| 国产精品久久国产精品99盘| 国产亚洲精久久久久久无码AV| 久久精品国产亚洲AV蜜臀色欲 | 欧美伊人久久大香线蕉综合 | 国产69精品久久久久观看软件| 性欧美大战久久久久久久久| 国产福利电影一区二区三区久久久久成人精品综合 | 99久久夜色精品国产网站| 久久人人爽人人爽人人片AV不| 99国内精品久久久久久久 | 香港aa三级久久三级老师2021国产三级精品三级在| 久久久久久久久久久精品尤物| 久久九九有精品国产23百花影院| 精品一二三区久久aaa片| 国产巨作麻豆欧美亚洲综合久久| 久久久久久夜精品精品免费啦| 四虎影视久久久免费| 国产精品热久久毛片| a高清免费毛片久久| 久久久久亚洲Av无码专| 久久无码高潮喷水| 久久久久国产一区二区| 久久99国产精品久久99果冻传媒|