【程式設計筆記】執行緒池實現原始碼(從POCO中剝離出來)
阿新 • • 發佈:2018-11-09
原始碼下載: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,執行緒預設棧引數為0(1MB)
*/
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