您的位置:首页 > 编程语言 > C语言/C++

C++实现多线程安全的单例模式

2014-10-29 11:01 260 查看
根据自己另外那篇文章: 弄的:http://blog.chinaunix.net/uid-25958655-id-4297540.html
WINDOWS VC++2010下测试通过

MultiThreadSingleton.h:

#ifndef MULTI_THREAD_SINGLETON_H_ 

#define MULTI_THREAD_SINGLETON_H_

#ifdef WIN32

#include<iostream>

#include<windows.h>

#endif //WIN32

#ifdef WIN32

class locker

{

public: 

    inline locker() { m_hMutex=CreateMutex(NULL,FALSE,NULL); std::cout<<"Locker::Locker()
" ;} 

    inline ~locker() { CloseHandle(m_hMutex); } 

    inline void lock() { WaitForSingleObject(m_hMutex, INFINITE); } 

    inline void unlock() { ReleaseMutex(m_hMutex); } 

private: 

    HANDLE m_hMutex;

};

#endif

/* 

 * this class is responsible for the
running log of tinyJSE 

 * there should only exist one instance of tinyLog, 

 * so we use singleton to implement tinyLog 

 */ 

class tinyLog 



public: 

    static tinyLog *GetInstance(); 

    static void WriteLog(const char *FORMAT,...); 

    int iTestThread;

private: 

    tinyLog(); 

    ~tinyLog(); 

private: 

        static tinyLog *log; //设置为static

    static locker llock; 

}; 

#endif

MultiThreadSingleton.cpp:

点击(此处)折叠或打开

#ifdef WIN32

#include<iostream>

#include<windows.h>

#endif //WIN32

#include "MultiThreadSingleton.h"

tinyLog * tinyLog::log = NULL; 

locker tinyLog::llock;

tinyLog::tinyLog() 



    printf("called tinyLog::tinyLog()\n");



  

tinyLog::~tinyLog() 





  

/* 

 * get the pointer to the only instance of tinyLog 

 * use double check to assure only one instance is created 

 */ 

tinyLog * tinyLog::GetInstance() 



    if(NULL == log) 

    {//double check 

        llock.lock(); 

        if(NULL == log) 

        { 

            log = new tinyLog(); //这里最好换成{ tinyLog * tmpLog=new
tinyLog(); log=tmpLog; } 原因请看我另外一篇"C++中多线程Singleton的实现"

            

        } 

        llock.unlock(); 

    } 

    return log; 



  

/* 

 * Unified handling of the log of tinyJSE 

 */ 

void tinyLog::WriteLog(const char *FORMAT,...) 



    va_list args; 

  

    va_start(args, FORMAT); 

  

    llock.lock(); 

  

    vfprintf(stdout,FORMAT,args); 

  

    llock.unlock(); 

  

    va_end(args); 

  

}

main.cpp:

#ifdef WIN32

#include<iostream>

#include<windows.h>

#endif

#include "MultiThreadSingleton.h"

DWORD WINAPI Fun1Proc(

    LPVOID lpParameter

    )

{

    std::cout<<"thread
"<< (int)lpParameter<< ":
" ;

    tinyLog *pty1=tinyLog::GetInstance();

    pty1->iTestThread ++;

    std::cout<< "in
Fun1Proc thread pty="<< pty1 << "
"<< std::endl ;

    Sleep(20000);

    return 0;

}

int main()

{

    HANDLE hThread[10];

    int i;

    for(i=0; i<10; i++)

        hThread[i] = CreateThread(NULL, 0, Fun1Proc, (LPVOID)i, 0, NULL);

    std::cin>>i;

    

    return 0;

}

以下是运行结果: 虽然结果看起来杂乱无章: 但是我们看到tinyLog()构造函数中只被调用的了一次, 且他们的地址都相同:

Locker::Locker() thread
thread 0thread thread thread thread thread 2thread threa

d thread : 37481: 569called tinyLog::tinyLog()

: : : : : : : : in Fun1Proc
thread pty=in Fun1Proc thread pty=in Fun1Proc
thread

 pty=in Fun1Proc thread pty=in Fun1Proc
thread pty=in Fun1Proc thread pty=in Fun

1Proc thread pty=in Fun1Proc thread pty=in Fun1Proc
thread pty=in Fun1Proc threa

d pty=00397250003972500039725000397250003972500039725000397250003972500039725000

397250
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: