Reputation: 17258
Is there any way to create a threadpool only using C++ or Windows C++ functions? I dont have access to boost or any libraries (I can access code project but couldnt find anything non-unix) and I am finding it hard to find a way to implement a threadpool.
I am using VS2010 which doesnt support the C++11 threading yet, hence why I'm a little stuck!
Upvotes: 3
Views: 4806
Reputation: 24887
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);
};
Upvotes: 4
Reputation: 1697
In case your target is Windows Vista or later you can use this thread pool: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686980%28v=vs.85%29.aspx
The page also has a example in C++.
Upvotes: 4
Reputation: 2318
There is an API for managing thread pools, here is a link: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686766(v=vs.85).aspx. You might want to find a library that wraps it, though, as it is complicated.
Upvotes: 1