3

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!

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
intrigued_66
  • 16,082
  • 51
  • 118
  • 189
  • Re: "Is there any way to create a threadpool only using C++ or Windows C++ functions?". Yes. How'd you think every single thread pool library on Earth works? None of them have any special access to the operating system or the compiler, nor do they require it. It isn't *that* trivial though. – In silico Apr 03 '12 at 08:38
  • The function you want is [CreateThread](http://msdn.microsoft.com/en-us/library/bb202727.aspx). See [here](http://msdn.microsoft.com/en-us/library/aa270957%28v=vs.60%29.aspx). – David Schwartz Apr 03 '12 at 08:40
  • @DavidSchwartz, CreateThread does not create a thread pool. – Lubo Antonov Apr 03 '12 at 09:12
  • @lucas1024: A thread pool is just a pool of threads. – David Schwartz Apr 03 '12 at 09:15
  • 1
    @David: And the whole "pooling" part is really quite complex and important. – Puppy Apr 03 '12 at 09:25

4 Answers4

4

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++.

BertR
  • 1,657
  • 11
  • 12
4

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);
};
Martin James
  • 24,453
  • 3
  • 36
  • 60
  • Thanks Matrin for providing a simple implementation of a thread pool. How can I check the status of existing threads before assigning a new task to the thread from the thread pool? – Tariq Jul 10 '14 at 09:49
1

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.

Lubo Antonov
  • 2,301
  • 14
  • 18
1

Improve Scalability With New Thread Pool APIs

Community
  • 1
  • 1
Ashish Kasma
  • 3,594
  • 7
  • 26
  • 29