It's fairly easy. You need some classes:
Task class with a 'run' method - something for the pool user to override to build up their own tasks.
A producer-consumer objectQueue for the threads to wait on for work. If you have std::deque, that's fairly easy. If not, you'll have to code up your own queue type. As well as the queue class, you need othe synchro stuff, maybe a CriticalSection/Mutex to protect the queue and a semaphore for the threads to wait on.
A threadPool class - something that contains the P-C queue, submit(TaskClass aTask) method and other stuff.
A pile of threads created in the threadPool ctor - use CreateThread and pass the threadPool instance as the lpParam parameter so that the threads can cast it back again to gain access to the threadPool.
The threads wait on the threadPool->objectQueue for work, eg:
// 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);
};