1. 程式人生 > >【程式設計筆記】執行緒池實現原始碼(從POCO中剝離出來)

【程式設計筆記】執行緒池實現原始碼(從POCO中剝離出來)

原始碼下載:https://download.csdn.net/download/fzuim/10625204

CThreadPool類

/***************************************************************************** 
    *  @COPYRIGHT NOTICE 
    *  @Copyright (c) 2018, Fzuim 
    *  @All rights reserved 

    *  @file     : ThreadPool.h 
    *  @version  : ver 1.0 

    *  @author
: Fzuim * @date : 2018/8/20 10:36 * @brief : 執行緒池類 *****************************************************************************/
#ifndef Fzuim_ThreadPool_INCLUDE #define Fzuim_ThreadPool_INCLUDE #include "Runnable.h" #include "PooledThread.h" #include "PooledMutex.h" class CThreadPool { public
: CThreadPool(int v_iMinCapacity = 2, int v_iMaxCapacity = 16, int v_iIdleTime = 60, int v_iStackSize = 0); ~CThreadPool(); static CThreadPool& GetDefaultPool(); void Start(CRunnable& v_Target); void StopAll(); void JoinAll(); //等待所有執行緒完成(並非退出) void
Collect(); //手動整理,從執行緒池停止並移除空閒過久的執行緒。整個框架也會進行自動整理 int GetUsedThreadNum() const; int GetAllocatedThreadNum() const; int GetAvailableThreadNum() const; void AddMaxThreadNum(int v_i); protected: void HouseKeep(); CPooledThread* GetThread(); private: typedef std::vector<CPooledThread*> ThreadVec; int m_iMinCapacity; int m_iMaxCapacity; int m_iIdleTime; int m_iStackSize; int m_iHouseKeep; ThreadVec m_vecThreads; mutable CThreadMutex m_Mutex; //mutable修飾的變數,將永遠處於可變的狀態,即使在一個const函式中。 }; #endif
/***************************************************************************** 
    *  @COPYRIGHT NOTICE 
    *  @Copyright (c) 2018, Fzuim 
    *  @All rights reserved 

    *  @file     : ThreadPool.cpp 
    *  @version  : ver 1.0 

    *  @author   : Fzuim 
    *  @date     : 2018/8/20 10:35 
    *  @brief    : 執行緒池
*****************************************************************************/

#include "stdafx.h"
#include "ThreadPool.h"

/*
 *  描述:執行緒池建構函式
 *  預設建立最小2個,最多16個執行緒,空閒超時時間60s,執行緒預設棧引數為01MB)
 */
CThreadPool::CThreadPool( int v_iMinCapacity /*= 2*/, int v_iMaxCapacity /*= 16*/, int v_iIdleTime /*= 60*/, int v_iStackSize /*= 0*/ ):
    m_iMinCapacity(v_iMinCapacity),
    m_iMaxCapacity(v_iMaxCapacity),
    m_iIdleTime(v_iIdleTime),
    m_iStackSize(v_iStackSize),
    m_iHouseKeep(0)
{
    assert (m_iMinCapacity >= 1 && m_iMaxCapacity >= m_iMinCapacity && m_iIdleTime > 0);

    for (int i = 0; i < m_iMaxCapacity; ++i)
    {
        CPooledThread* pThread = new CPooledThread(m_iStackSize);
        m_vecThreads.push_back(pThread);
        pThread->Start(); //將執行緒啟動起來
    }
}

CThreadPool::~CThreadPool()
{
    StopAll();
}

//對傳入的函式指標,從執行緒池獲取一條執行緒並附加執行
void CThreadPool::Start( CRunnable& v_Target )
{
    GetThread()->Start(CThread::PRIO_NORMAL_IMPL, v_Target);
}

//停止執行緒池所有執行緒
void CThreadPool::StopAll()
{
    CFastLock FastLock(m_Mutex);

    for (ThreadVec::iterator it = m_vecThreads.begin(); it != m_vecThreads.end(); ++it)
    {
        (*it)->Release();
    }
    m_vecThreads.clear();
}

//獲取正在使用中的執行緒數量
int CThreadPool::GetUsedThreadNum() const
{
    CFastLock FastLock(m_Mutex);

    int iCount = 0;
    for (ThreadVec::const_iterator it = m_vecThreads.begin(); it != m_vecThreads.end(); ++it)
    {
        if (!(*it)->Idle()) ++iCount;
    }
    return iCount;
}

//獲取執行緒池總的執行緒數
int CThreadPool::GetAllocatedThreadNum() const
{
    CFastLock FastLock(m_Mutex);

    return int(m_vecThreads.size());;
}

/*
 *  獲取可用執行緒個數=已建立執行緒空閒數+最大執行緒數-已建立執行緒數
 */
int CThreadPool::GetAvailableThreadNum() const
{
    CFastLock FastLock(m_Mutex);

    int iCount = 0;
    for (ThreadVec::const_iterator it = m_vecThreads.begin(); it != m_vecThreads.end(); ++it)
    {
        if ((*it)->Idle()) ++iCount;
    }

    return (int) (iCount + m_iMaxCapacity - m_vecThreads.size());
}

//從執行緒池獲取一個執行緒(空閒狀態)
CPooledThread* CThreadPool::GetThread()
{
    CFastLock FastLock(m_Mutex);

    //每32次獲取執行緒,就進行一次執行緒池整理
    if (++m_iHouseKeep == 32)
    {
        HouseKeep();
    }

    CPooledThread* pThread = NULL;
    for (ThreadVec::iterator it = m_vecThreads.begin(); !pThread && it != m_vecThreads.end(); ++it)
    {
        if ((*it)->Idle()) pThread = *it;
    }

    if (!pThread)
    {
        if ((int)m_vecThreads.size() < m_iMaxCapacity)
        {
            pThread = new CPooledThread(m_iStackSize);
            try
            {
                pThread->Start();
                m_vecThreads.push_back(pThread);
            }
            catch(...)
            {
                delete pThread;
                pThread = NULL;
                throw;
            }
        }
        else
        {
            throw NoThreadAvailableException();
        }
    }

    //啟用狀態設定
    pThread->Activate();
    return pThread;
}

//等待所有執行緒完成任務
void CThreadPool::JoinAll()
{
    CFastLock FastLock(m_Mutex);

    for (ThreadVec::iterator it = m_vecThreads.begin(); it != m_vecThreads.end(); ++it)
    {
        (*it)->Join();
    }
}

//執行緒池整理:根據當前執行緒狀態,進行調整
void CThreadPool::HouseKeep()
{
    m_iHouseKeep = 0;
    if((int)m_vecThreads.size() <= m_iMinCapacity)
    {
        return;
    }

    ThreadVec IdleThreads; //空閒執行緒數
    ThreadVec ExpiredThreads; //空閒過久執行緒
    ThreadVec ActiveThreads; //活動執行緒

    //手動分配vector大小,提高效率
    IdleThreads.reserve(m_vecThreads.size());
    ActiveThreads.reserve(m_vecThreads.size());

    //對執行緒池進行一次分類整理
    for(ThreadVec::iterator it = m_vecThreads.begin(); it != m_vecThreads.end(); ++it)
    {
        if((*it)->Idle())
        {
            if ((*it)->IdleTime() < m_iIdleTime) //和設定的超時時間對比
            {
                IdleThreads.push_back(*it); //超時不久
            }
            else
            {
                ExpiredThreads.push_back(*it); //超時太久
            }
        }
        else
        {
            ActiveThreads.push_back(*it); //活動的執行緒
        }
    }

    int iActiveNum = (int)ActiveThreads.size();
    int iLimit = iActiveNum + (int)IdleThreads.size();
    iLimit = iLimit < m_iMinCapacity ? m_iMinCapacity : iLimit;

    //將空閒太久和空閒不久的執行緒進行一次合併,合併到空閒不久的末尾
    //這邊主要是為了:繼續講空閒太久的執行緒利用起來,防止頻繁的建立銷燬執行緒
    IdleThreads.insert(IdleThreads.end(), ExpiredThreads.begin(), ExpiredThreads.end());
    m_vecThreads.clear();

    for(ThreadVec::iterator it = IdleThreads.begin(); it != IdleThreads.end(); ++it)
    {
        if (iActiveNum < iLimit)
        {
            m_vecThreads.push_back(*it); //從超時執行緒內=》執行緒池
            ++iActiveNum;
        }
        else
        {
            (*it)->Release();
        }
    }

    //重新整合:活動+空閒
    m_vecThreads.insert(m_vecThreads.end(), ActiveThreads.begin(), ActiveThreads.end());
}

//增加執行緒池裡的執行緒數
void CThreadPool::AddMaxThreadNum( int v_i )
{
    CFastLock FastLock(m_Mutex);

    assert(m_iMaxCapacity + v_i >= m_iMinCapacity);
    m_iMaxCapacity += v_i;
    HouseKeep(); //這邊進行執行緒池整理,是為了進一步將空閒執行緒利用起來
}

//執行緒池整理
void CThreadPool::Collect()
{
    CFastLock FastLock(m_Mutex);
    HouseKeep();
}

//////////////////////////////////////////////////////////////////////////
class CThreadPoolSingleton
{
public:
    CThreadPoolSingleton()
    {
        m_pPool = NULL;
    }

    ~CThreadPoolSingleton()
    {
        if (m_pPool)
        {
            delete m_pPool;
            m_pPool = NULL;
        }
    }

    CThreadPool* GetPool()
    {
        CFastLock FastLock(m_Mutex);

        if (!m_pPool)
        {
            m_pPool = new CThreadPool();
        }

        return m_pPool;
    }
private:
    CThreadPool* m_pPool;
    CThreadMutex m_Mutex;
};

static CThreadPoolSingleton g_DefaultPool;

//獲取預設執行緒池
CThreadPool& CThreadPool::GetDefaultPool()
{
    return *g_DefaultPool.GetPool();
}

CPooledThread類

/***************************************************************************** 
    *  @COPYRIGHT NOTICE 
    *  @Copyright (c) 2018, Fzuim 
    *  @All rights reserved 

    *  @file     : PooledThread.h 
    *  @version  : ver 1.0 

    *  @author   : Fzuim 
    *  @date     : 2018/8/20 10:41 
    *  @brief    : 執行緒類===》執行緒池
*****************************************************************************/
#ifndef Fzuim_PooledThread_INCLUDE
#define Fzuim_PooledThread_INCLUDE

#include "Runnable.h"
#include "Thread.h"
#include "PooledEvent.h"
#include "PooledMutex.h"
#include <ctime>

class CPooledThread : public CRunnable
{
public:
    CPooledThread(int v_iStackSize = 0);
    ~CPooledThread();

    void Start();
    void Start(CThread::_enPriority v_enPriority, CRunnable& v_Target);
    void Run();
    void Release();
    BOOL Idle();
    int IdleTime();
    void Activate();
    void Join();

private:
    volatile bool        m_bIdle;
    volatile std::time_t m_IdleTime;

    CRunnable*           m_pTarget;
    CThread              m_Thread;

    CPooledEvent         m_hStartedEvt; //標識執行緒是否已經在執行
    CPooledEvent         m_hTargetReadyEvt; //標識是否設定了:執行緒執行的回撥函式
    CPooledEvent         m_hTargetCompletedEvt; //標識執行緒執行任務是否完成

    CThreadMutex         m_ThreadMutex;
};

#endif
/***************************************************************************** 
    *  @COPYRIGHT NOTICE 
    *  @Copyright (c) 2018, Fzuim 
    *  @All rights reserved 

    *  @file     : PooledThread.cpp 
    *  @version  : ver 1.0 

    *  @author   : Fzuim 
    *  @date     : 2018/8/20 10:42 
    *  @brief    : 執行緒類===》執行緒池 
*****************************************************************************/
#include "stdafx.h"
#include "PooledThread.h"

CPooledThread::CPooledThread( int v_iStackSize /*= 0*/ ):
    m_bIdle(true),
    m_IdleTime(0),
    m_pTarget(NULL),
    m_hTargetCompletedEvt(false)
{
    m_Thread.SetStackSize(v_iStackSize);
    m_IdleTime = std::time(NULL);
}

CPooledThread::~CPooledThread()
{

}

//執行緒池初始化的時候,建立CPooledThread物件時,都將真正意義上建立一個執行緒
//由於CPooledThread也是繼承與CRunnable,所以建立的執行緒將主動執行CPooledThread::Run()
//外層使用執行緒池執行緒時,將函式指標傳入m_pTarget,即可實現自動執行
void CPooledThread::Start()
{
    m_Thread.Start(*this);
    m_hStartedEvt.Wait();
}

//執行緒啟動,主要是將m_hTargetReadyEvt事件設定為觸發狀態
void CPooledThread::Start(CThread::_enPriority v_enPriority, CRunnable& v_Target)
{
    CFastLock FastLock(m_ThreadMutex);

    assert(m_pTarget == NULL);

    m_pTarget = &v_Target;
    m_Thread.SetPriority(v_enPriority);
    m_hTargetReadyEvt.Set();
}

//執行緒池裡的執行緒執行框架,就在這個Run函式裡面
void CPooledThread::Run()
{
    m_hStartedEvt.Set();
    for (;;)
    {
        m_hTargetReadyEvt.Wait();
        m_ThreadMutex.lock();
        if (m_pTarget)
        {
            m_ThreadMutex.unlock();
            try
            {
                m_pTarget->Run();
            }
            catch(...)
            {
                throw SystemException("PooledThread::Run Error.");
            }

            CFastLock FastLock(m_ThreadMutex);
            m_pTarget = NULL;
            m_IdleTime = std::time(NULL);
            m_bIdle = true;
            m_hTargetCompletedEvt.Set();
            m_Thread.SetPriority(CThread::PRIO_NORMAL_IMPL);
        }
        else
        {
            m_ThreadMutex.unlock();
            break;
        }
    }
}

//執行緒釋放
void CPooledThread::Release()
{
    m_ThreadMutex.lock();
    m_pTarget = NULL;
    m_ThreadMutex.unlock();

    m_hTargetReadyEvt.Set(); //讓Run直接執行,自動退出執行緒
    //等待執行緒退出
    if (m_Thread.TryJoin(10000))
    {
        delete this;
    }
}

//返回執行緒繁忙狀態
BOOL CPooledThread::Idle()
{
    return m_bIdle;
}

//返回執行緒空閒時間
int CPooledThread::IdleTime()
{
    CFastLock FastLock(m_ThreadMutex);
    return (int) (std::time(NULL) - m_IdleTime);
}

//執行緒啟用相關狀態設定
void CPooledThread::Activate()
{
    CFastLock FastLock(m_ThreadMutex);

    assert(m_bIdle);
    m_bIdle = false;
    m_hTargetCompletedEvt.Reset();
}

//等待執行緒完成,同步操作
void CPooledThread::Join()
{
    if (m_pTarget)
    {
        m_hTargetCompletedEvt.Wait();
    }
}


CThread類

/***************************************************************************** 
    *  @COPYRIGHT NOTICE 
    *  @Copyright (c) 2018, Fzuim 
    *  @All rights reserved 

    *  @file     : Thread.h 
    *  @version  : ver 1.0 

    *  @author   : Fzuim 
    *  @date     : 2018/8/20 10:17 
    *  @brief    : 執行緒類
*****************************************************************************/

#ifndef Fzuim_Thread_INCLUDE
#define Fzuim_Thread_INCLUDE

#include "GlobalHead.h"
#include "Runnable.h"

class CThread
{
public:

#if defined(_DLL)
    typedef DWORD (WINAPI *Entry)(LPVOID);
#else
    typedef unsigned (__stdcall *Entry)(void*);
#endif

    enum _enPriority
    {
        PRIO_LOWEST_IMPL  = THREAD_PRIORITY_LOWEST,
        PRIO_LOW_IMPL     = THREAD_PRIORITY_BELOW_NORMAL,
        PRIO_NORMAL_IMPL  = THREAD_PRIORITY_NORMAL,
        PRIO_HIGH_IMPL    = THREAD_PRIORITY_ABOVE_NORMAL,
        PRIO_HIGHEST_IMPL = THREAD_PRIORITY_HIGHEST
    };

    CThread();
    ~CThread();

    void Start(CRunnable& v_Target);
    void SetPriority(_enPriority v_enPrio);
    _enPriority GetPriority() const;
    void SetStackSize(int v_iSize);
    int GetStackSize() const;

    bool TryJoin(long v_lngMilliseconds);
    bool IsRunning() const;

protected:
#if defined(_DLL)
    static DWORD WINAPI runnableEntry(LPVOID pThread);
#else
    static unsigned __stdcall runnableEntry(void* pThread);
#endif

    void Create(Entry v_Ent, void* v_pData);
    void ThreadCleanup();

private:
    CRunnable* m_pRunnableTarget;

    HANDLE m_hThread;
    DWORD m_dwThreadId;
    int m_iPriority;
    int m_iStackSize;
};

#endif
/***************************************************************************** 
    *  @COPYRIGHT NOTICE 
    *  @Copyright (c) 2018, Fzuim 
    *  @All rights reserved 

    *  @file     : Thread.cpp 
    *  @version  : ver 1.0 

    *  @author   : Fzuim 
    *  @date     : 2018/8/20 10:37 
    *  @brief    : 執行緒類 
*****************************************************************************/

#include "stdafx.h"
#include "Thread.h"

CThread::CThread():
    m_pRunnableTarget(NULL),
    m_hThread(NULL),
    m_dwThreadId(0),
    m_iPriority(PRIO_NORMAL_IMPL),
    m_iStackSize(0)
{

}

CThread::~CThread()
{
    if (m_hThread)
    {
        CloseHandle(m_hThread);
        m_hThread = NULL;
    }
}

#if defined(_DLL)
DWORD WINAPI CThread::runnableEntry(LPVOID pThread)
#else
unsigned __stdcall CThread::runnableEntry(void* pThread)
#endif
{
    reinterpret_cast<CThread*>(pThread)->m_pRunnableTarget->Run();
    return 0;
}

//啟動執行緒
void CThread::Start( CRunnable& v_Target )
{
    if (!IsRunning())
    {
        m_pRunnableTarget = &v_Target;
        Create(runnableEntry, this);
    }
    else
    {
        throw SystemException("thread already running");
    }
}

//設定執行緒優先順序
void CThread::SetPriority( _enPriority v_enPrio )
{
    m_iPriority = v_enPrio;
}

//獲取執行緒優先順序
CThread::_enPriority CThread::GetPriority() const
{
    return _enPriority(m_iPriority);
}

//設定執行緒堆疊空間大小
void CThread::SetStackSize( int v_iSize )
{
    m_iStackSize = v_iSize;
}

//獲取執行緒堆疊空間大小
int CThread::GetStackSize() const
{
    return m_iStackSize;
}

//判斷執行緒是否在執行
bool CThread::IsRunning() const
{
    if (m_hThread)
    {
        DWORD dwEc = 0;
        return GetExitCodeThread(m_hThread, &dwEc) && dwEc == STILL_ACTIVE;
    }
    return false;
}

//建立執行緒,最底層實現:CreateThread或_beginthreadex
void CThread::Create( Entry v_Ent, void* v_pData )
{
#if defined(_DLL)
    m_hThread = CreateThread(NULL, m_iStackSize, v_Ent, v_pData, 0, &m_dwThreadId);
#else
    unsigned threadId;
    m_hThread = (HANDLE) _beginthreadex(NULL, m_iStackSize, v_Ent, this, 0, &threadId);
    m_dwThreadId = static_cast<DWORD>(threadId);
#endif

    if (!m_hThread){
        throw SystemException("cannot create thread");
    }
    if (m_iPriority != PRIO_NORMAL_IMPL && !SetThreadPriority(m_hThread, m_iPriority)){
        throw SystemException("cannot set thread priority");
    }
}

//等待執行緒退出
bool CThread::TryJoin( long v_lngMilliseconds )
{
    if (!m_hThread)
    {
        return true;
    }

    switch(WaitForSingleObject(m_hThread, v_lngMilliseconds + 1))
    {
    case WAIT_TIMEOUT:
        return false;
    case WAIT_OBJECT_0:
        ThreadCleanup();
        return true;
    default:
        throw SystemException("cannot join thread");
    }
}

//執行緒控制代碼釋放
void CThread::ThreadCleanup()
{
    if (!m_hThread) return;
    if (CloseHandle(m_hThread)) m_hThread = NULL;
}

CRunnable類

/***************************************************************************** 
    *  @COPYRIGHT NOTICE 
    *  @Copyright (c) 2018, Fzuim 
    *  @All rights reserved 

    *  @file     : Runnable.h 
    *  @version  : ver 1.0 

    *  @author   : Fzuim 
    *  @date     : 2018/8/20 10:19 
    *  @brief    : 純虛擬函式,介面類
*****************************************************************************/

#ifndef Fzuim_Runnable_INCLUDE
#define Fzuim_Runnable_INCLUDE

class CRunnable
{
public:
    CRunnable(){};
    virtual ~CRunnable(){};

    virtual void Run() = 0;
};

#endif

CRunnableAdapter類

/***************************************************************************** 
    *  @COPYRIGHT NOTICE 
    *  @Copyright (c) 2018, Fzuim 
    *  @All rights reserved 

    *  @file     : RunnableAdapter.h 
    *  @version  : ver 1.0 

    *  @author   : Fzuim 
    *  @date     : 2018/8/20 11:09 
    *  @brief    : 程序回調適配器類 
*****************************************************************************/
#ifndef Fzuim_RunnableAdapter_INCLUDE
#define Fzuim_RunnableAdapter_INCLUDE

#include "Runnable.h"

template <class C>
class CRunnableAdapter : public CRunnable
{
public:
    typedef void (C::*Callback)();

    CRunnableAdapter(C& object, Callback method): _pObject(&object), _method(method)
    {
    }

    CRunnableAdapter(const CRunnableAdapter& ra): _pObject(ra._pObject), _method(ra._method)
    {
    }

    ~CRunnableAdapter()
    {
    }

    CRunnableAdapter& operator = (const CRunnableAdapter& ra)
    {
        _pObject = ra._pObject;
        _method  = ra._method;
        return *this;
    }

    void Run()
    {
        (_pObject->*_method)();
    }

private:
    CRunnableAdapter();

    C*       _pObject;
    Callback _method;
};

#endif

CThreadMutex類

/***************************************************************************** 
    *  @COPYRIGHT NOTICE 
    *  @Copyright (c) 2018, Fzuim 
    *  @All rights reserved 

    *  @file     : PooledMutex.h 
    *  @version  : ver 1.0 

    *  @author   : Fzuim 
    *  @date     : 2018/8/20 10:40 
    *  @brief    : 執行緒鎖 
*****************************************************************************/
#ifndef Fzuim_PooledMutex_INCLUDE
#define Fzuim_PooledMutex_INCLUDE

#include "GlobalHead.h"

class CThreadMutex
{
public:
    CThreadMutex();
    ~CThreadMutex();

    void lock();
    void lock(long v_lngMilliseconds);
    bool tryLock();
    void unlock();
private:
    bool m_bInitialized;
    CRITICAL_SECTION m_criticalSection;
};

//自動加解鎖,利用C++ 構造和解構函式的特性
class CFastLock
{
public:
    CFastLock(CThreadMutex& v_Mutex);
    ~CFastLock();
private:
    CThreadMutex* m_pMutex;
};

#endif
/***************************************************************************** 
    *  @COPYRIGHT NOTICE 
    *  @Copyright (c) 2018, Fzuim 
    *  @All rights reserved 

    *  @file     : PooledMutex.cpp 
    *  @version  : ver 1.0 

    *  @author   : Fzuim 
    *  @date     : 2018/8/20 10:40 
    *  @brief    : 執行緒鎖 
*****************************************************************************/
#include "stdafx.h"
#include "PooledMutex.h"

CThreadMutex::CThreadMutex()
{
    m_bInitialized = TRUE;
    InitializeCriticalSection(&m_criticalSection);
}

CThreadMutex::~CThreadMutex()
{
    if (m_bInitialized)
        DeleteCriticalSection(&m_criticalSection);
    m_bInitialized = FALSE;
}

void CThreadMutex::lock()
{
    if (!m_bInitialized)
        return;

    EnterCriticalSection(&m_criticalSection);
}

bool CThreadMutex::tryLock()
{
    try
    {
        return TryEnterCriticalSection(&m_criticalSection) != 0;
    }
    catch (...)
    {
    }
    throw SystemException("cannot lock mutex");
}

void CThreadMutex::unlock()
{
    if (!m_bInitialized)
        return;

    LeaveCriticalSection(&m_criticalSection);
}

CFastLock::CFastLock( CThreadMutex& v_Mutex )
{
    m_pMutex = &v_Mutex;
    if (m_pMutex)
    {
        m_pMutex->lock();
    }
}

CFastLock::~CFastLock()
{
    if (m_pMutex)
    {
        m_pMutex->unlock();
    }
}

CPooledEvent類

/***************************************************************************** 
    *  @COPYRIGHT NOTICE 
    *  @Copyright (c) 2018, Fzuim 
    *  @All rights reserved 

    *  @file     : PooledEvent.h 
    *  @version  : ver 1.0 

    *  @author   : Fzuim 
    *  @date     : 2018/8/20 10:38 
    *  @brief    : 執行緒池事件類 
*****************************************************************************/
#ifndef Fzuim_PooledEvent_INCLUDE
#define Fzuim_PooledEvent_INCLUDE

#include "GlobalHead.h"

class CPooledEvent
{
public:
    CPooledEvent(bool v_bAutoReset = true);
    ~CPooledEvent();

    void Set();
    void Wait();
    bool Wait(const long v_lngmilliseconds);
    void Reset();
private:
    HANDLE m_hEvent;
};

#endif
/***************************************************************************** 
    *  @COPYRIGHT NOTICE 
    *  @Copyright (c) 2018, Fzuim 
    *  @All rights reserved 

    *  @file     : PooledEvent.cpp 
    *  @version  : ver 1.0 

    *  @author   : Fzuim 
    *  @date     : 2018/8/20 10:39 
    *  @brief    : 執行緒池事件類  
*****************************************************************************/
#include "stdafx.h"
#include "PooledEvent.h"

CPooledEvent::CPooledEvent( bool v_bAutoReset /*= true*/ )
{
    m_hEvent = CreateEvent(NULL, v_bAutoReset ? FALSE : TRUE, FALSE, NULL);
    if (!m_hEvent)
    {
        throw SystemException("cannot create event");
    }
}

CPooledEvent::~CPooledEvent()
{
    if (m_hEvent)
    {
        CloseHandle(m_hEvent);
        m_hEvent = NULL;
    }
}

void CPooledEvent::Set()
{
    if (!SetEvent(m_hEvent))
    {
        throw SystemException("cannot signal event");
    }
}

void CPooledEvent::Wait()
{
    switch (WaitForSingleObject(m_hEvent, INFINITE))
    {
    case WAIT_OBJECT_0:
        return;
    default:
        throw SystemException("wait for event failed");
    }
}

bool CPooledEvent::Wait( const long v_lngmilliseconds )
{
    switch (WaitForSingleObject(m_hEvent, v_lngmilliseconds + 1))
    {
    case WAIT_TIMEOUT:
        return false;
    case WAIT_OBJECT_0:
        return true;
    default:
        throw SystemException("wait for event failed");     
    }
}

void CPooledEvent::Reset()
{
    if (!ResetEvent(m_hEvent))
    {
        throw SystemException("cannot reset event");
    }
}

CPooledException類

/***************************************************************************** 
    *  @COPYRIGHT NOTICE 
    *  @Copyright (c) 2018, Fzuim 
    *  @All rights reserved 

    *  @file     : Exception.h 
    *  @version  : ver 1.0 

    *  @author   : Fzuim 
    *  @date     : 2018/8/20 10:39 
    *  @brief    : 異常類 
*****************************************************************************/
#ifndef Fzuim_Exception_INCLUDE
#define Fzuim_Exception_INCLUDE

#include <stdexcept>

class CPooledException: public std::exception
{
public:
    CPooledException(const std::string& msg, int code = 0);

    CPooledException(const std::string& msg, const std::string& arg, int code = 0);

    CPooledException(const std::string& msg, const CPooledException& nested, int code = 0);

    CPooledException(const CPooledException& exc);

    ~CPooledException() throw();

    CPooledException& operator = (const CPooledException& exc);

    virtual const char* name() const throw();

    virtual const char* className() const throw();

    virtual const char* what() const throw();

    const CPooledException* nested() const;

    const std::string& message() const;

    int code() const;

    std::string displayText() const;

    virtual CPooledException* clone() const;

    virtual void rethrow() const;

protected:
    CPooledException(int code = 0);

    void message(const std::string& msg);

    void extendedMessage(const std::string& arg);

private:
    std::string  _msg;
    CPooledException*  _pNested;
    int          _code;
};

//巨集實現類定義
#define FZUIM_DECLARE_EXCEPTION_CODE(CLS, BASE, CODE) \
    class CLS: public BASE                                                          \
        {                                                                           \
        public:                                                                     \
        CLS(int code = CODE);                                                       \
        CLS(const std::string& msg, int code = CODE);                               \
        CLS(const std::string& msg, const std::string& arg, int code = CODE);       \
        CLS(const std::string& msg, const CPooledException& exc, int code = CODE);  \
        CLS(const CLS& exc);                                                        \
        ~CLS() throw();                                                                \
        CLS& operator = (const CLS& exc);                                           \
        const char* name() const throw();                                           \
        const char* className() const throw();                                      \
        CPooledException* clone() const;                                            \
        void rethrow() const;                                                       \
        };

#define FZUIM_DECLARE_EXCEPTION(CLS, BASE) \
    FZUIM_DECLARE_EXCEPTION_CODE(CLS, BASE, 0)

//巨集實現類介面
#define FZUIM_IMPLEMENT_EXCEPTION(CLS, BASE, NAME)                                                  \
    CLS::CLS(int code): BASE(code)                                                                  \
    {                                                                                               \
    }                                                                                               \
    CLS::CLS(const std::string& msg, int code): BASE(msg, code)                                     \
    {                                                                                               \
    }                                                                                               \
    CLS::CLS(const std::string& msg, const std::string& arg, int code): BASE(msg, arg, code)        \
    {                                                                                               \
    }                                                                                               \
    CLS::CLS(const std::string& msg, const CPooledException& exc, int code): BASE(msg, exc, code)   \
    {                                                                                               \
    }                                                                                               \
    CLS::CLS(const CLS& exc): BASE(exc)                                                             \
    {                                                                                               \
    }                                                                                               \
    CLS::~CLS() throw()                                                                                \
    {                                                                                               \
    }                                                                                               \
    CLS& CLS::operator = (const CLS& exc)                                                           \
    {                                                                                               \
        BASE::operator = (exc);                                                                     \
        return *this;                                                                               \
    }                                                                                               \
    const char* CLS::name() const throw()                                                           \
    {                                                                                               \
        return NAME;                                                                                \
    }                                                                                               \
    const char* CLS::className() const throw()                                                      \
    {                                                                                               \
        return typeid(*this).name();                                                                \
    }                                                                                               \
    CPooledException* CLS::clone() const                                                            \
    {                                                                                               \
        return new CLS(*this);                                                                      \
    }                                                                                               \
    void CLS::rethrow() const                                                                       \
    {                                                                                               \
        throw *this;                                                                                \
    }


FZUIM_DECLARE_EXCEPTION(RuntimeException, CPooledException)
FZUIM_DECLARE_EXCEPTION(NoThreadAvailableException, RuntimeException)
FZUIM_DECLARE_EXCEPTION(SystemException, RuntimeException)

#endif
/***************************************************************************** 
    *  @COPYRIGHT NOTICE 
    *  @Copyright (c) 2018, Fzuim 
    *  @All rights reserved 

    *  @file     : Exception.cpp 
    *  @version  : ver 1.0 

    *  @author   : Fzuim 
    *  @date     : 2018/8/20 10:39 
    *  @brief    : 異常類 
*****************************************************************************/
#include "stdafx.h"
#include "Exception.h"
#include <typeinfo>

CPooledException::CPooledException(int code): _pNested(0), _code(code)
{
}


CPooledException::CPooledException(
            
           

相關推薦

no