スレッドセキュリティの単一モード実装


#include <iostream>
#include <vector>
#include <bitset>
#include <assert.h>
#include <Windows.h>
#include <process.h>


using namespace std;


class CSingleton
{
private:
    class CAssistForSingleton
    {
    private:
        CRITICAL_SECTION m_cs;


    public:
        CAssistForSingleton()
        {
            InitializeCriticalSection(&m_cs);
        }


        ~CAssistForSingleton()
        {
            DeleteCriticalSection(&m_cs);
        }


    public:
        void Lock()
        {
            EnterCriticalSection(&m_cs);
        }


        void UnLock()
        {
            LeaveCriticalSection(&m_cs);
        }
    };


private:
    static CAssistForSingleton m_refSycObj;
    static CSingleton *m_pInstance;


    static int m_nData;


private:
    CSingleton()
    {


    }


public:
    static CSingleton *GetInstatnce()
    {
        m_refSycObj.Lock();
        if (NULL == m_pInstance)
        {
            m_pInstance = new CSingleton;
            cout<<"new CSingleton"<<endl;
        }
        m_refSycObj.UnLock();


        return m_pInstance;
    }


public:
    static int GetData() 
    {
        return m_nData;
    }


    static void SetData(int nData)
    {
        m_refSycObj.Lock();
        m_nData = nData;
        m_refSycObj.UnLock();
    }
};


CSingleton::CAssistForSingleton CSingleton::m_refSycObj = CSingleton::CAssistForSingleton();
CSingleton *CSingleton::m_pInstance = NULL;
int CSingleton::m_nData = 0;


unsigned int WINAPI ThreadFun(void *)
{
    cout<<"Launcher Thread"<<endl;
    
    for(int i = 0 ; i < 99999999 ; i++)
    {
        CSingleton *pSingl = CSingleton::GetInstatnce();
        if (NULL != pSingl)
        {
            pSingl->SetData(i);
        }


        Sleep(500);
    }


    return 0;
}


int main(int argv, char *argc[])
{
    uintptr_t HandleThread[10];
    unsigned int nThreadId = 0;
    for(int i = 0 ; i < 10 ; i++)
    {
        HandleThread[i] = _beginthreadex(NULL, 0, ThreadFun, NULL, 0, &nThreadId);
    }


    WaitForMultipleObjects(10, (const HANDLE *)HandleThread, TRUE, INFINITE);


    return 0;
}