/ / Note, this code I used for a long time, I deleted the automatic adjustment of the size of the code (because he was not yet mature)
/************************************************* *****************
* Thread Pool For Win32
* VC + + 6, BC + + 5.5 (Free), the GCC (Free)
* Update: 2004.6.9 llBird wushaojian@21cn.com
Use:
1):
Void threadfunc (void * p)
(
//…
)
ThreadPool tp;
For (i = 0; i <100; i + +)
Tp.Call (threadfunc);
ThreadPool tp (20); / / 20 for the initial size of the thread pool
Tp.Call (threadfunc, lpPara);
Tp.AdjustSize (50); / / 50
Tp.AdjustSize (-30); / / decrease 30
2):
Class MyThreadJob: public ThreadJob / / thread object from ThreadJob expansion
(
Public:
Virtual void DoJob (void * p) / / Since the definition of virtual function
(
//….
)
);
MyThreadJob mt [10];
ThreadPool tp;
For (i = 0; i <100 i + +)
Tp.Call (mt + i) / / tp.Call (mt + i, para);
************************************************** *****************/
# Ifndef _ThreadPool_H_
# Define _ThreadPool_H_
# Pragma warning (disable: 4530)
# Pragma warning (disable: 4786)
# Include <cassert>
# Include <vector>
# Include <queue>
# Include <windows.h>
Class ThreadJob / / working-class
(
Public:
/ / Thread pool call for the virtual function
Virtual void DoJob (pPara void *) = 0;
);
Class ThreadPool
(
Public:
/ / Size of the thread pool dwNum
ThreadPool (DWORD dwNum = 4): _lThreadNum (0), _lRunningNum (0)
(
InitializeCriticalSection (& _csThreadVector);
InitializeCriticalSection (& _csWorkQueue);
CreateEvent _EventComplete = (0, false, false, NULL);
CreateEvent _EventEnd = (0, true, false, NULL);
CreateSemaphore _SemaphoreCall = (0, 0, 0×7FFFFFFF, NULL);
CreateSemaphore _SemaphoreDel = (0, 0, 0×7FFFFFFF, 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);
)
/ / Size of the thread pool adjustment
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);
Assert (pNew-> _Handle);
)
LeaveCriticalSection (& _csThreadVector);
)
Else
(
INum *= 1;
ReleaseSemaphore (_SemaphoreDel, iNum> _lThreadNum? _lThreadNum: INum, NULL);
)
Return (int) _lThreadNum;
)
/ / Call Thread Pool
Void Call (void (* pFunc) (void *), void * pPara = NULL)
(
Assert (pFunc);
EnterCriticalSection (& _csWorkQueue);
_JobQueue.push (New JobItem (pFunc, pPara));
LeaveCriticalSection (& _csWorkQueue);
ReleaseSemaphore (_SemaphoreCall, 1, NULL);
)
/ / Call Thread Pool
Inline void Call (ThreadJob * p, void * pPara = NULL)
(
Call (CallProc, new CallProcPara (p, pPara));
)
/ / End of the thread pool and, in parallel, wait
Bool EndAndWait (DWORD dwWaitTime = INFINITE)
(
SetEvent (_EventEnd);
Return WaitForSingleObject (_EventComplete, dwWaitTime) == WAIT_OBJECT_0;
)
/ / End of the thread pool
Inline void End ()
(
SetEvent (_EventEnd);
)
Inline DWORD Size ()
(
Return (DWORD) _lThreadNum;
)
Inline DWORD GetRunningSize ()
(
Return (DWORD) _lRunningNum;
)
Bool IsRunning ()
(
Return _lRunningNum> 0;
)
Protected:
/ / Work thread
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);
/ / Delete threads signal response
If (wr WAIT_OBJECT_0 + == 1)
Break;
/ / Queue, the user operation
EnterCriticalSection (& pThreadPoolObj-> _csWorkQueue);
If (fHasJob =! PThreadPoolObj-> _JobQueue.empty ())
(
PJob = pThreadPoolObj-> _JobQueue.front ();
PThreadPoolObj-> _JobQueue.pop ();
Assert (pJob);
)
LeaveCriticalSection (& pThreadPoolObj-> _csWorkQueue);
/ / By the end of the thread signals the end of threads (signal the end of threads & Is there work)
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); / / users run operations
Delete pJob;
PThread-> _fIsRunning = false;
InterlockedDecrement (& pThreadPoolObj-> _lRunningNum);
)
)
/ / Delete their own structure
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) / / end all threads
SetEvent (pThreadPoolObj-> _EventComplete);
Return 0;
)
/ / Virtual function call User Object
Static void CallProc (void * pPara)
(
CallProcPara * cp = static_cast <CallProcPara *> (pPara);
Assert (cp);
If (cp)
(
Cp-> _pObj-> DoJob (cp-> _pPara);
Delete cp;
)
)
/ / User object structure
Struct CallProcPara
(
ThreadJob * _pObj; / / User Object
Void * _pPara; / / user parameters
CallProcPara (ThreadJob * p, * pPara void): _pObj (p), _pPara (pPara) ();
);
/ / User function structure
Struct JobItem
(
Void (* _pFunc) (void *);// function
Void * _pPara; / / Parameter
JobItem (void (* pFunc) (void *) = NULL, void * pPara = NULL): _pFunc (pFunc), _pPara (pPara) ();
);
/ / Thread pool thread structure
Struct ThreadItem
(
HANDLE _Handle; / / thread handle
ThreadPool * _pThis; / / thread pool indicators
DWORD _dwLastBeginTime; / / start running last time
DWORD _dwCount; / / frequency operation
Bool _fIsRunning;
ThreadItem (pthis ThreadPool *): _pThis (pthis), _Handle (NULL), _dwLastBeginTime (0), _dwCount (0), _fIsRunning (false) ();
~ ThreadItem ()
(
If (_Handle)
(
CloseHandle (_Handle);
_Handle = NULL;
)
)
);
Std:: queue <JobItem *> _JobQueue; / / Work Queue
Std:: vector <ThreadItem *> _ThreadVector; / / thread data
CRITICAL_SECTION _csThreadVector, _csWorkQueue; / / Work Queue critical, critical data threads
HANDLE _EventEnd, _EventComplete, _SemaphoreCall, _SemaphoreDel; / / End notice completed, the work signals, signal deleted threads
Long _lThreadNum, _lRunningNum; / / number of threads running several threads
);
# Endif / / _ThreadPool_H_