此线程池所依赖的线程类,请参看《一个Windows C++的线程类实现》:该线程池程序没有完全按照C++类的设计思想来做,在CWorker和CThreadPoolExecutor类的封装上还需要做些改动。
头文件:
// CThreadPool.h: interface for the CThreadPool class. // ////////////////////////////////////////////////////////////////////// #ifndef __C_PLUS_CTHREADPOOL_HEADE #define __C_PLUS_CTHREADPOOL_HEADE #include <set> #include <list> #include <windows.h> #include "CThread.h" using namespace std; class CThreadPoolExecutor { public: CThreadPoolExecutor(); ~CThreadPoolExecutor(); // 初始化线程池,创建minThreads个线程 BOOL Init(unsigned int minThreads, unsigned int maxThreads, unsigned int maxPendingTasks); // 执行任务,若当前任务列表没满,则将此任务加入列表,返回TRUE // 若当前任务列表满,但小于最大线程数,将创建线程执行此任务,返回TRUE // 若当前任务列表满,且等于最大线程数,则丢弃此任务,返回FALSE BOOL Execute(Runnable* pRunnable); // 终止线程池,先制止塞入任务, // 然后等待直到任务列表为空, // 然后设置最小线程数量为0, // 清空垃圾丢中的任务 void Terminate(); // 返回线程池中当前的线程数量 unsigned int GetThreadPoolSize(); //friend class CWorker; Runnable * GetTask(); static unsigned int WINAPI StaticThreadFunc(void* arg); public: class CWorker:public CThread { public: CWorker(CThreadPoolExecutor* pThreadPool, Runnable* pFirstTask=NULL); ~CWorker(); void Run(); private: CThreadPoolExecutor* m_pThreadPool; Runnable* m_pFirstTask; volatile BOOL m_bRun; }; typedef std::set<CWorker*> ThreadPool; typedef std::list<Runnable*> Tasks; typedef Tasks::iterator TasksItr; typedef ThreadPool::iterator ThreadPoolItr; ThreadPool m_ThreadPool; ThreadPool m_TrashThread; Tasks m_Tasks; CRITICAL_SECTION m_csTasksLock; CRITICAL_SECTION m_csThreadPoolLock; volatile BOOL m_bRun; volatile BOOL m_bEnableInsertTask; volatile unsigned int m_minThreads; volatile unsigned int m_maxThreads; volatile unsigned int m_maxPendingTasks; }; #endifCPP文件:
// CThreadPool.cpp: implementation of the CThreadPool class. // ////////////////////////////////////////////////////////////////////// #include "CThreadPoolExecutor.h" CThreadPoolExecutor::CWorker::CWorker(CThreadPoolExecutor* pThreadPool, Runnable* pFirstTask): m_pThreadPool(pThreadPool), m_pFirstTask(pFirstTask), m_bRun(TRUE) { } CThreadPoolExecutor::CWorker::~CWorker() { } // 直线任务的工作线程 // 当前没有任务时,如果当前线程数量大于最小线程时,减少线程 // 否则,执行清理程序,将线程类给释放掉 void CThreadPoolExecutor::CWorker::Run() { Runnable* pTask = NULL; while ( m_bRun) { if ( NULL == m_pFirstTask) { pTask = m_pThreadPool->GetTask(); } else { pTask = m_pFirstTask; m_pFirstTask = NULL; } if ( NULL == pTask) { EnterCriticalSection(&(m_pThreadPool->m_csThreadPoolLock)); if ( m_pThreadPool->GetThreadPoolSize()> m_pThreadPool->m_minThreads) { ThreadPoolItr itr = m_pThreadPool->m_ThreadPool.find(this); if ( itr!=m_pThreadPool->m_ThreadPool.end()) { m_pThreadPool->m_ThreadPool.erase(itr); m_pThreadPool->m_TrashThread.insert(this); } m_bRun = FALSE; } else { ThreadPoolItr itr = m_pThreadPool->m_TrashThread.begin(); while ( itr!=m_pThreadPool->m_TrashThread.end()) { (*itr)->Join(); delete (*itr); m_pThreadPool->m_TrashThread.erase(itr); itr = m_pThreadPool->m_TrashThread.begin(); } }// end else LeaveCriticalSection(&(m_pThreadPool->m_csThreadPoolLock)); continue; }// end if else { pTask->Run(); pTask = NULL; } }// end while m_bRun } CThreadPoolExecutor::CThreadPoolExecutor():m_bRun(FALSE), m_bEnableInsertTask(FALSE) { InitializeCriticalSection(&m_csTasksLock); InitializeCriticalSection(&m_csThreadPoolLock); } CThreadPoolExecutor::~CThreadPoolExecutor() { Terminate(); DeleteCriticalSection(&m_csTasksLock); DeleteCriticalSection(&m_csThreadPoolLock); } BOOL CThreadPoolExecutor::Init(unsigned int minThreads, unsigned int maxThreads, unsigned int maxPendingTasks) { if ( minThreads ==0) { return FALSE; } if ( maxThreads < minThreads) { return FALSE; } m_minThreads = minThreads; m_maxThreads = maxThreads; m_maxPendingTasks = maxPendingTasks; unsigned int i = m_ThreadPool.size(); for ( ;i<minThreads; i++) { CWorker* pWorker = new CWorker(this); if ( NULL == pWorker) { return FALSE; } EnterCriticalSection(&m_csThreadPoolLock); m_ThreadPool.insert(pWorker); LeaveCriticalSection(&m_csThreadPoolLock); pWorker->Start(); } m_bRun = TRUE; m_bEnableInsertTask = TRUE; return TRUE; } BOOL CThreadPoolExecutor::Execute(Runnable* pRunnable) { if ( !m_bEnableInsertTask) { return FALSE; } if ( NULL == pRunnable) { return FALSE; } if ( m_Tasks.size()>=m_maxPendingTasks) { if (m_ThreadPool.size()<m_maxThreads) { CWorker* pWorker = new CWorker(this, pRunnable); if ( NULL == pWorker) { return FALSE; } EnterCriticalSection(&m_csThreadPoolLock); m_ThreadPool.insert(pWorker); LeaveCriticalSection(&m_csThreadPoolLock); pWorker->Start(); } else { return FALSE; } } else { EnterCriticalSection(&m_csTasksLock); m_Tasks.push_back(pRunnable); LeaveCriticalSection(&m_csTasksLock); } return TRUE; } Runnable* CThreadPoolExecutor::GetTask() { Runnable* Task = NULL; EnterCriticalSection(&m_csTasksLock); if ( !m_Tasks.empty()) { Task = m_Tasks.front(); m_Tasks.pop_front(); } LeaveCriticalSection(&m_csTasksLock); return Task; } unsigned int CThreadPoolExecutor::GetThreadPoolSize() { return m_ThreadPool.size(); } void CThreadPoolExecutor::Terminate() { m_bEnableInsertTask = FALSE; while (m_Tasks.size()>0) { Sleep(1); } m_bRun = FALSE; m_minThreads = 0; m_maxThreads = 0; m_maxPendingTasks = 0; while ( m_ThreadPool.size()>0) { Sleep(1); } EnterCriticalSection(&m_csThreadPoolLock); ThreadPoolItr itr = m_TrashThread.begin(); while (itr!=m_TrashThread.end()) { (*itr)->Join(); delete(*itr); m_TrashThread.erase(itr); itr = m_TrashThread.begin(); } LeaveCriticalSection(&m_csThreadPoolLock); }测试程序:
#include <stdio.h> #include "CThread.h" #include "CThreadPoolExecutor.h" class Example:public Runnable { public: ~Example() { printf("Example Destruction\n"); } void Run() { printf("Hello CThread\n"); } }; int main(int argc, char* argvp[]) { CThreadPoolExecutor* pExecutor = new CThreadPoolExecutor(); pExecutor->Init(2,10,50); Example exam; for ( int i=0; i<100; i++) { while ( !pExecutor->Execute(&exam)) { } } pExecutor->Terminate(); delete pExecutor; getchar(); return 0; }