- #ifndef _ThreadPool_H_
- #define _ThreadPool_H_
- #pragma warning(disable: 4530)
- #pragma warning(disable: 4786)
- #include <cassert>
- #include <vector>
- #include <queue>
- #include <windows.h>
- using namespace std;
- class ThreadJob //工作基類
- {
- public:
- //供線程池調用的虛函數
- virtual void DoJob(void *pPara) = 0;
- };
- class ThreadPool
- {
- public:
- //dwNum 線程池規模
- ThreadPool(DWORD dwNum = 4) : _lThreadNum(0), _lRunningNum(0)
- {
- InitializeCriticalSection(&_csThreadVector);
- InitializeCriticalSection(&_csWorkQueue);
- _EventComplete = CreateEvent(0, false, false, NULL);
- _EventEnd = CreateEvent(0, true, false, NULL);
- _SemaphoreCall = CreateSemaphore(0, 0, 0x7FFFFFFF, NULL);
- _SemaphoreDel = CreateSemaphore(0, 0, 0x7FFFFFFF, NULL);
- assert(_SemaphoreCall != INVALID_HANDLE_VALUE);
- assert(_EventComplete != INVALID_HANDLE_VALUE);
- assert(_EventEnd != INVALID_HANDLE_VALUE);
- assert(_SemaphoreDel != INVALID_HANDLE_VALUE);
- AdjustSize(dwNum <= 0 ? 4 : dwNum);
- }
- ~ThreadPool()
- {
- DeleteCriticalSection(&_csWorkQueue);
- CloseHandle(_EventEnd);
- CloseHandle(_EventComplete);
- CloseHandle(_SemaphoreCall);
- CloseHandle(_SemaphoreDel);
- vector<ThreadItem*>::iterator iter;
- for(iter = _ThreadVector.begin(); iter != _ThreadVector.end(); iter++)
- {
- if(*iter)
- delete *iter;
- }
- DeleteCriticalSection(&_csThreadVector);
- }
- //調整線程池規模
- int AdjustSize(int iNum)
- {
- if(iNum > 0)
- {
- ThreadItem *pNew;
- EnterCriticalSection(&_csThreadVector);
- for(int _i=0; _i<iNum; _i++)
- {
- _ThreadVector.push_back(pNew = new ThreadItem(this));
- assert(pNew);
- pNew->_Handle = CreateThread(NULL, 0, DefaultJobProc, pNew, 0, NULL);
- // set priority
- SetThreadPriority(pNew->_Handle, THREAD_PRIORITY_BELOW_NORMAL);
- assert(pNew->_Handle);
- }
- LeaveCriticalSection(&_csThreadVector);
- }
- else
- {
- iNum *= -1;
- ReleaseSemaphore(_SemaphoreDel, iNum > _lThreadNum ? _lThreadNum : iNum, NULL);
- }
- return (int)_lThreadNum;
- }
- //調用線程池
- void Call(void (*pFunc)(void *), void *pPara = NULL)
- {
- assert(pFunc);
- EnterCriticalSection(&_csWorkQueue);
- _JobQueue.push(new JobItem(pFunc, pPara));
- LeaveCriticalSection(&_csWorkQueue);
- ReleaseSemaphore(_SemaphoreCall, 1, NULL);
- }
- //調用線程池
- inline void Call(ThreadJob * p, void *pPara = NULL)
- {
- Call(CallProc, new CallProcPara(p, pPara));
- }
- //結束線程池, 並同步等待
- bool EndAndWait(DWORD dwWaitTime = INFINITE)
- {
- SetEvent(_EventEnd);
- return WaitForSingleObject(_EventComplete, dwWaitTime) == WAIT_OBJECT_0;
- }
- //結束線程池
- inline void End()
- {
- SetEvent(_EventEnd);
- }
- inline DWORD Size()
- {
- return (DWORD)_lThreadNum;
- }
- inline DWORD GetRunningSize()
- {
- return (DWORD)_lRunningNum;
- }
- bool IsRunning()
- {
- return _lRunningNum > 0;
- }
- protected:
- //工作線程
- static DWORD WINAPI DefaultJobProc(LPVOID lpParameter = NULL)
- {
- ThreadItem *pThread = static_cast<ThreadItem*>(lpParameter);
- assert(pThread);
- ThreadPool *pThreadPoolObj = pThread->_pThis;
- assert(pThreadPoolObj);
- InterlockedIncrement(&pThreadPoolObj->_lThreadNum);
- HANDLE hWaitHandle[3];
- hWaitHandle[0] = pThreadPoolObj->_SemaphoreCall;
- hWaitHandle[1] = pThreadPoolObj->_SemaphoreDel;
- hWaitHandle[2] = pThreadPoolObj->_EventEnd;
- JobItem *pJob;
- bool fHasJob;
- for(;;)
- {
- DWORD wr = WaitForMultipleObjects(3, hWaitHandle, false, INFINITE);
- //響應刪除線程信號
- if(wr == WAIT_OBJECT_0 + 1)
- break;
- //從隊列裏取得用戶作業
- EnterCriticalSection(&pThreadPoolObj->_csWorkQueue);
- if(fHasJob = !pThreadPoolObj->_JobQueue.empty())
- {
- pJob = pThreadPoolObj->_JobQueue.front();
- pThreadPoolObj->_JobQueue.pop();
- assert(pJob);
- }
- LeaveCriticalSection(&pThreadPoolObj->_csWorkQueue);
- //受到結束線程信號 確定是否結束線程(結束線程信號 && 是否還有工作)
- if(wr == WAIT_OBJECT_0 + 2 && !fHasJob)
- break;
- if(fHasJob && pJob)
- {
- InterlockedIncrement(&pThreadPoolObj->_lRunningNum);
- pThread->_dwLastBeginTime = GetTickCount();
- pThread->_dwCount++;
- pThread->_fIsRunning = true;
- pJob->_pFunc(pJob->_pPara); //運行用戶作業
- delete pJob;
- pThread->_fIsRunning = false;
- InterlockedDecrement(&pThreadPoolObj->_lRunningNum);
- }
- }
- //刪除自身結構
- EnterCriticalSection(&pThreadPoolObj->_csThreadVector);
- pThreadPoolObj->_ThreadVector.erase(find(pThreadPoolObj->_ThreadVector.begin(), pThreadPoolObj->_ThreadVector.end(), pThread));
- LeaveCriticalSection(&pThreadPoolObj->_csThreadVector);
- delete pThread;
- InterlockedDecrement(&pThreadPoolObj->_lThreadNum);
- if(!pThreadPoolObj->_lThreadNum) //所有線程結束
- SetEvent(pThreadPoolObj->_EventComplete);
- return 0;
- }
- //調用用戶對象虛函數
- static void CallProc(void *pPara)
- {
- CallProcPara *cp = static_cast<CallProcPara *>(pPara);
- assert(cp);
- if(cp)
- {
- cp->_pObj->DoJob(cp->_pPara);
- delete cp;
- }
- }
- //用戶對象結構
- struct CallProcPara
- {
- ThreadJob* _pObj;//用戶對象
- void *_pPara;//用戶參數
- CallProcPara(ThreadJob* p, void *pPara) : _pObj(p), _pPara(pPara) { };
- };
- //用戶函數結構
- struct JobItem
- {
- void (*_pFunc)(void *);//函數
- void *_pPara; //參數
- JobItem(void (*pFunc)(void *) = NULL, void *pPara = NULL) : _pFunc(pFunc), _pPara(pPara) { };
- };
- //線程池中的線程結構
- struct ThreadItem
- {
- HANDLE _Handle; //線程句柄
- ThreadPool *_pThis; //線程池的指針
- DWORD _dwLastBeginTime; //最後一次運行開始時間
- DWORD _dwCount; //運行次數
- bool _fIsRunning;
- ThreadItem(ThreadPool *pthis) : _pThis(pthis), _Handle(NULL), _dwLastBeginTime(0), _dwCount(0), _fIsRunning(false) { };
- ~ThreadItem()
- {
- if(_Handle)
- {
- CloseHandle(_Handle);
- _Handle = NULL;
- }
- }
- };
- std::queue<JobItem *> _JobQueue; //工作隊列
- std::vector<ThreadItem *> _ThreadVector; //線程數據
- CRITICAL_SECTION _csThreadVector, _csWorkQueue; //工作隊列臨界, 線程數據臨界
- HANDLE _EventEnd, _EventComplete, _SemaphoreCall, _SemaphoreDel;//結束通知, 完成事件, 工作信號, 刪除線程信號
- long _lThreadNum, _lRunningNum; //線程數, 運行的線程數
- };
- #endif //_ThreadPool_H_
//...
}
ThreadPool tp;
for(i=0; i<100; i++)
tp.Call(threadfunc);
ThreadPool tp(20);//20爲初始線程池規模
tp.Call(threadfunc, lpPara);