版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fzuim/article/details/82023240
源码下载: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(const std::string& msg, int code): _msg(msg), _pNested(0), _code(code)
{
}
CPooledException::CPooledException(const std::string& msg, const std::string& arg, int code): _msg(msg), _pNested(0), _code(code)
{
if (!arg.empty())
{
_msg.append(": ");
_msg.append(arg);
}
}
CPooledException::CPooledException(const std::string& msg, const CPooledException& nested, int code): _msg(msg), _pNested(nested.clone()), _code(code)
{
}
CPooledException::CPooledException(const CPooledException& exc):
std::exception(exc),
_msg(exc._msg),
_code(exc._code)
{
_pNested = exc._pNested ? exc._pNested->clone() : 0;
}
CPooledException::~CPooledException() throw()
{
delete _pNested;
}
CPooledException& CPooledException::operator = (const CPooledException& exc)
{
if (&exc != this)
{
delete _pNested;
_msg = exc._msg;
_pNested = exc._pNested ? exc._pNested->clone() : 0;
_code = exc._code;
}
return *this;
}
const char* CPooledException::name() const throw()
{
return "Exception";
}
const char* CPooledException::className() const throw()
{
return typeid(*this).name();
}
const char* CPooledException::what() const throw()
{
return name();
}
std::string CPooledException::displayText() const
{
std::string txt = name();
if (!_msg.empty())
{
txt.append(": ");
txt.append(_msg);
}
return txt;
}
void CPooledException::extendedMessage(const std::string& arg)
{
if (!arg.empty())
{
if (!_msg.empty()) _msg.append(": ");
_msg.append(arg);
}
}
CPooledException* CPooledException::clone() const
{
return new CPooledException(*this);
}
void CPooledException::rethrow() const
{
throw *this;
}
inline const CPooledException* CPooledException::nested() const
{
return _pNested;
}
inline const std::string& CPooledException::message() const
{
return _msg;
}
inline void CPooledException::message(const std::string& msg)
{
_msg = msg;
}
inline int CPooledException::code() const
{
return _code;
}
FZUIM_IMPLEMENT_EXCEPTION(RuntimeException, CPooledException, "Runtime exception")
FZUIM_IMPLEMENT_EXCEPTION(NoThreadAvailableException, RuntimeException, "No thread available")
FZUIM_IMPLEMENT_EXCEPTION(SystemException, RuntimeException, "System exception")
全局头文件包含 GlobalHead.h
#ifndef Fzuim_GlobalHead_INCLUDE
#define Fzuim_GlobalHead_INCLUDE
#include <iostream>
#include <Windows.h>
#include <assert.h>
#include <vector>
#include "Exception.h"
#endif
使用栗子
// Fzuim_ThreadPool.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "./ThreadPool/ThreadPool.h"
#include "./ThreadPool/RunnableAdapter.h"
class CTest
{
public:
CTest(){};
~CTest(){};
void Test()
{
try
{
CThreadPool pool;
printf("allocate:%d\n", pool.GetAllocatedThreadNum());
printf("available:%d\n", pool.GetAvailableThreadNum());
CRunnableAdapter<CTest> ra(*this, &CTest::Proc);
pool.Start(ra);
pool.JoinAll();
pool.AddMaxThreadNum(2);
printf("allocate:%d\n", pool.GetAllocatedThreadNum());
printf("available:%d\n", pool.GetAvailableThreadNum());
}
catch(...)
{
}
}
void Proc()
{
for (int i = 0; i < 10; ++i)
{
printf("%d===>%d\n", i, 10 - i);
}
}
};
int _tmain(int argc, _TCHAR* argv[])
{
CTest test;
test.Test();
system("pause");
return 0;
}