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)  
  • 相关阅读:
    查询自动生成Guid列
    Appium运行时报does not have permission android.permission.CLEAR_APP_USER_DATA to clear data
    小米手机
    SoapUI简介和入门实例解析
    Postman高级应用——流程控制、调试、公共函数、外部数据文件
    Postman高级应用——串行传参和动态传参详解
    Fiddler抓包工具使用详解
    接口测试简介
    soapui基础知识
    接口测试文档规范
  • 原文地址:https://www.cnblogs.com/wenshanzh/p/2831312.html
Copyright © 2011-2022 走看看