1. 程式人生 > >伺服器公共庫開發--執行緒安全的singleton類, 可配置的執行緒鎖管理類

伺服器公共庫開發--執行緒安全的singleton類, 可配置的執行緒鎖管理類

在伺服器開發中,大量的使用了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)   #endifclass 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()
{
    
return0;
}

int CThreadMutex::UnLock()
{
    
return0;
}

#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"usingnamespace 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"usingnamespace 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;

    
return0;
}


posted on 2008-08-01 23:32 那誰 閱讀(5168) 評論(2)  編輯 收藏 引用 所屬分類: C\C++設計模式伺服器設計