This is pretty easy. You need several classes:
A task class with a "run" method is something for a pool user to override his own tasks.
Consumer-consumer-producer object for threads awaiting work. If you have std :: deque, this is pretty easy. If not, you will have to code your own queue type. Besides the queue class, you will need synchronization data, perhaps CriticalSection / Mutex to protect the queue and semaphore for the threads that are waiting.
The threadPool class is what contains the PC queue, submit (TaskClass aTask) and other things.
A bunch of threads created in threadPool ctor - use CreateThread and pass the threadPool instance as the lpParam parameter so that threads can return it back to access threadPool.
Threads are waiting on threadPool-> objectQueue to work, for example:
// header
class threadPool; class task { friend class threadPool; private: threadPool *myPool; public: virtual void run()=0; }; class PCSqueue{ private: CRITICAL_SECTION access; deque<task*> *objectQueue; HANDLE queueSema; public: PCSqueue(); void push(task *ref); bool pop(task **ref,DWORD timeout); }; class threadPool { private: int threadCount; public: PCSqueue *queue; threadPool(int initThreads); static DWORD _stdcall staticThreadRun(void *param){ threadPool *myPool=(threadPool *)param; task *thisTask; while (myPool->queue->pop(&thisTask,INFINITE)){ thisTask->run(); } } void submit(task *aTask); };
// cpp
PCSqueue::PCSqueue(){ objectQueue=new deque<task*>; InitializeCriticalSection(&access); queueSema=CreateSemaphore(NULL,0,MAXINT,NULL); }; void PCSqueue::push(task *ref){ EnterCriticalSection(&access); objectQueue->push_front(ref); LeaveCriticalSection(&access); ReleaseSemaphore(queueSema,1,NULL); }; bool PCSqueue::pop(task **ref,DWORD timeout){ if (WAIT_OBJECT_0==WaitForSingleObject(queueSema,timeout)) { EnterCriticalSection(&access); *ref=objectQueue->back(); objectQueue->pop_back(); LeaveCriticalSection(&access); return(true); } else return(false); }; threadPool::threadPool(int initThreads){ queue=new PCSqueue(); for(threadCount=0;threadCount!=initThreads;threadCount++){ CreateThread(NULL,0,staticThreadRun,this,0,0); }; }; void threadPool::submit(task *aTask){ aTask->myPool=this; queue->push(aTask); };