C ++ Windows线程池(非boost / c ++ 11) [英] C++ Windows Thread pool (non-boost/c++11)

查看:164
本文介绍了C ++ Windows线程池(非boost / c ++ 11)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法只使用C ++或Windows C ++函数创建线程池?我没有访问boost或任何库(我可以访问代码项目,但couldnt找到任何非unix),我发现很难找到一种方法来实现线程池。



我使用VS2010,它不支持C + + 11线程,因此为什么我有点卡住了!

解决方案

p>这很容易。您需要一些类:



具有run方法的任务类 - 用于池用户覆盖以构建自己的任务的任务类。



生产者 - 消费者对象线程等待工作的队列。如果你有std :: deque,这是相当容易。如果没有,你必须编写自己的队列类型。除了队列类,你需要同步的东西,也许一个CriticalSection / Mutex保护队列和信号量的线程等待。



一个threadPool类 - 包含PC队列,提交(TaskClass aTask)方法和其他东西。



在threadPool ctor中创建的一堆线程 - 使用CreateThread并传递threadPool实例作为lpParam参数,以便线程可以再次投射它以获得访问threadPool。



线程等待threadPool-> objectQueue工作,例如: / p>

// header

  class threadPool; 

类任务{
friend类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(任务**参考,DWORD超时){
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);
};


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!

解决方案

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);
};

这篇关于C ++ Windows线程池(非boost / c ++ 11)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆