zoukankan      html  css  js  c++  java
  • 【转】单例模式 C++实现 多线程安全

    转自:http://blog.csdn.net/joanlynnlove/article/details/7462254

    项目中需要在多线程环境下,输出日志到标准输出,以下是实现过程。

    首先,我们需要一个锁类,能够自动初始化,并且降低耦合。

    1. /* 
    2.  * locker.h 
    3.  * 
    4.  *  Created on: Apr 14, 2012 
    5.  *      Author: joan 
    6.  */  
    7.   
    8. #ifndef LOCKER_H_  
    9. #define LOCKER_H_  
    10.   
    11. #include "../OPTION.h"  
    12.   
    13. class locker  
    14. {  
    15. public:  
    16.     inline locker(){        pthread_mutex_init(&mutex,NULL);}  
    17.     inline ~locker(){       pthread_mutex_destroy(&mutex);}  
    18.     inline void lock(){     pthread_mutex_lock(&mutex);}  
    19.     inline void unlock(){   pthread_mutex_unlock(&mutex);}  
    20. private:  
    21.     pthread_mutex_t mutex;  
    22. };  
    23.   
    24. #endif /* LOCKER_H_ */  

    其次,声明日志类,重点是将构造函数私有化,将函数成员和数据成员声明为静态,添加实例指针和全局访问点。

    1. /* 
    2.  * log.h 
    3.  * 
    4.  *  Created on: Apr 8, 2012 
    5.  *      Author: joan 
    6.  */  
    7.   
    8. #ifndef LOG_H_  
    9. #define LOG_H_  
    10.   
    11. #include "../OPTION.h"  
    12. #include "locker.h"  
    13.   
    14. /* 
    15.  * this class is responsible for the running log of tinyJSE 
    16.  * there should only exist one instance of tinyLog, 
    17.  * so we use singleton to implement tinyLog 
    18.  */  
    19. class tinyLog  
    20. {  
    21. public:  
    22.     static tinyLog *GetInstance();  
    23.     static void WriteLog(const char *FORMAT,...);  
    24. private:  
    25.     tinyLog();  
    26.     ~tinyLog();  
    27. private:  
    28.         static tinyLog *log;  
    29. static locker llock;  
    30. };  
    31. #endif /* LOG_H_ */  

    然后是日志类的实现,注意全局访问点中使用double check提高性能。

    1. /* 
    2.  * log.cpp 
    3.  * 
    4.  *  Created on: Apr 8, 2012 
    5.  *      Author: joan 
    6.  */  
    7.   
    8. #include "../OPTION.h"  
    9. #include "log.h"  
    10.   
    11. tinyLog * tinyLog::log = NULL;  
    12. locker tinyLog::llock;  
    13.   
    14. tinyLog::tinyLog()  
    15. {  
    16. }  
    17.   
    18. tinyLog::~tinyLog()  
    19. {  
    20. }  
    21.   
    22. /* 
    23.  * get the pointer to the only instance of tinyLog 
    24.  * use double check to assure only one instance is created 
    25.  */  
    26. tinyLog *tinyLog::GetInstance()  
    27. {  
    28.     if(NULL == log)  
    29.     {//double check  
    30.         llock.lock();  
    31.         if(NULL == log)  
    32.         {  
    33.             log = new tinyLog();  
    34.         }  
    35.         llock.unlock();  
    36.     }  
    37.     return log;  
    38. }  
    39.   
    40. /* 
    41.  * Unified handling of the log of tinyJSE 
    42.  */  
    43. void tinyLog::WriteLog(const char *FORMAT,...)  
    44. {  
    45.     va_list args;  
    46.   
    47.     va_start(args, FORMAT);  
    48.   
    49.     llock.lock();  
    50.   
    51.     vfprintf(stdout,FORMAT,args);  
    52.   
    53.     llock.unlock();  
    54.   
    55.     va_end(args);  
    56.   
    57. }  

    使用该单例:

    1. #define PRINT(FORMAT,args...)   tinyLog::GetInstance()->WriteLog(FORMAT,##args)  
  • 相关阅读:
    VS 2008潜在强大的功能:提取EXE文件中的ICO等资源
    园友们注意:淘宝网上QQ会员 4钻 3元 等都为骗子行为
    Comet Async Process Request Handler
    WCF(Sender) to MSMQ to WCF(Receiver)
    ASP.NET Web Form GridView DetailsView Query Edit
    WCF NetTcp AsyncQueue Service
    Xml CDATA 序列化
    Sync Invoke Remoting Async Invoke
    .Net 4.0 Remoting ConcurrentQueue
    Socket Async Receive Data to LinkedList Buffer (telnet proxy server)
  • 原文地址:https://www.cnblogs.com/wenshanzh/p/2831312.html
Copyright © 2011-2022 走看看