在服务器开发中,大量的使用了singleton模式, 以我的工作为例, 用于打印log的类是一个singleton, 内存池管理器是一个singleton...虽然singleton模式实现起来不难, 但是为了避免重复开发, 我还是决定应该把这个类的实现单独拿出来,同时, singleton类还需要支持多线程,但是我从来不写多线程的服务器程序, 对多线程的支持可以通过预编译宏来实现.我把操作多线程锁, 以及singleton类都放在这篇文章中, 多线程锁仅支持linux.
threadmutex.h
/********************************************************************
created: 2008/08/01
filename: threadmutex.h
author: Lichuang
purpose: 线程锁类, 由是否定义宏__USE_THREAD__来决定是否使用该类
*********************************************************************/
#ifndef __THREAD_MUTEX_H__
#define __THREAD_MUTEX_H__
#ifdef __USE_THREAD__
#include <pthread.h>
#define THREAD_LOCK(tThreadMutex) tThreadMutex.Lock()
#define THREAD_UNLOCK(tThreadMutex) tThreadMutex.UnLock()
#else
#define THREAD_LOCK(tThreadMutex)
#define THREAD_UNLOCK(tThreadMutex)
#endif
class CThreadMutex
{
public:
CThreadMutex();
~CThreadMutex();
int Lock();
int UnLock();
private:
#ifdef __USE_THREAD__
pthread_mutex_t m_tThreadMutex;
#endif
};
#endif /* __THREAD_MUTEX_H__ */
threadmutex.cpp
/********************************************************************
created: 2008/08/01
filename: threadmutex.h
author: Lichuang
purpose: 线程锁类, 由是否定义宏__USE_THREAD__来决定是否使用该
线程锁类
*********************************************************************/
#include "threadmutex.h"
#ifdef __USE_THREAD__
CThreadMutex::CThreadMutex()
{
::pthread_mutex_init(&m_tThreadMutex, NULL);
}
CThreadMutex::~CThreadMutex()
{
::pthread_mutex_destroy(&m_tThreadMutex);
}
int CThreadMutex::Lock()
{
return ::pthread_mutex_lock(&m_tThreadMutex);
}
int CThreadMutex::UnLock()
{
return ::pthread_mutex_unlock(&m_tThreadMutex);
}
#else
CThreadMutex::CThreadMutex()
{
}
CThreadMutex::~CThreadMutex()
{
}
int CThreadMutex::Lock()
{
return 0;
}
int CThreadMutex::UnLock()
{
return 0;
}
#endif
singleton.h
/********************************************************************
created: 2008/08/01
filename: singleton.h
author: Lichuang
purpose: 实现单件模式的虚拟基类, 其它需要实现为singleton的类可以
继承自这个类
支持多线程, 采用智能指针实现自动回收内存
*********************************************************************/
#ifndef __SINGLETON_H__
#define __SINGLETON_H__
#include <memory>
#include "threadmutex.h"
using namespace std;
#define DECLARE_SINGLETON_CLASS( type ) \
friend class auto_ptr< type >; \
friend class CSingleton< type >;
template <class T>
class CSingleton
{
public:
static T* GetInstance();
protected:
CSingleton()
{
}
virtual ~CSingleton()
{
}
protected:
friend class auto_ptr<CSingleton>;
static auto_ptr<T> m_pInstance;
static CThreadMutex m_tThreadMutex;
};
template <class T>
auto_ptr<T> CSingleton<T>::m_pInstance;
template <class T>
CThreadMutex CSingleton<T>::m_tThreadMutex;
template <class T>
inline T* CSingleton<T>::GetInstance()
{
if (0 == m_pInstance.get())
{
THREAD_LOCK(m_tThreadMutex);
if (0 == m_pInstance.get())
{
m_pInstance.reset(::new T);
}
THREAD_UNLOCK(m_tThreadMutex);
}
return m_pInstance.get();
}
#endif /* __SINGLETON_H__ */
使用示例:
#include <iostream>
#include "singleton.h"
using namespace std;
class CTestSingleton
: public CSingleton<CTestSingleton>
{
public:
void Set(int a)
{
m_a = a;
}
int Get()
{
return m_a;
}
private:
CTestSingleton()
: m_a(0)
{
}
DECLARE_SINGLETON_CLASS(CTestSingleton)
private:
int m_a;
};
int main()
{
if (NULL == CTestSingleton::GetInstance())
{
cout << "GetInstance() error!" << endl;
}
cout << "before set: " << CTestSingleton::GetInstance()->Get() << endl;
CTestSingleton::GetInstance()->Set(100);
cout << "after set: " << CTestSingleton::GetInstance()->Get() << endl;
return 0;
}