项目中需要在多线程环境下,输出日志到标准输出,以下是实现过程。
首先,我们需要一个锁类,能够自动初始化,并且降低耦合。
/*
* 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)