项目中需要在多线程环境下,输出日志到标准输出,以下是实现过程。
首先,我们需要一个锁类,能够自动初始化,并且降低耦合。
/* * locker.h * * Created on: Apr 14, 2012 * Author: joan */ #ifndef LOCKER_H_ #define LOCKER_H_ #include "../OPTION.h" class locker { public: inline locker(){ pthread_mutex_init(&mutex,NULL);} inline ~locker(){ pthread_mutex_destroy(&mutex);} inline void lock(){ pthread_mutex_lock(&mutex);} inline void unlock(){ pthread_mutex_unlock(&mutex);} private: pthread_mutex_t mutex; }; #endif /* LOCKER_H_ */
其次,声明日志类,重点是将构造函数私有化,将函数成员和数据成员声明为静态,添加实例指针和全局访问点。
/* * log.h * * Created on: Apr 8, 2012 * Author: joan */ #ifndef LOG_H_ #define LOG_H_ #include "../OPTION.h" #include "locker.h" /* * 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,...); private: tinyLog(); ~tinyLog(); private: static tinyLog *log; static locker llock; }; #endif /* LOG_H_ */然后是日志类的实现,注意全局访问点中使用double check提高性能。
/* * log.cpp * * Created on: Apr 8, 2012 * Author: joan */ #include "../OPTION.h" #include "log.h" tinyLog * tinyLog::log = NULL; locker tinyLog::llock; tinyLog::tinyLog() { } 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(); } 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); }使用该单例:
#define PRINT(FORMAT,args...) tinyLog::GetInstance()->WriteLog(FORMAT,##args)