C++ Windows线程池(非boost/c++11)

3

有没有办法仅使用C++或Windows C++函数创建线程池? 我无法访问boost或任何库(我可以访问code project,但找不到非Unix的任何内容),而且我很难找到一种实现线程池的方法。

我正在使用VS2010,它尚不支持C++11线程,这就是为什么我有些困惑的原因!


回复:“有没有办法只使用C++或Windows C++函数创建线程池?” 是的。你认为地球上每个线程池库是如何工作的?它们都没有任何特殊访问操作系统或编译器的权限,也不需要它。但这并不是那么微不足道的事情。 - In silico
你需要的函数是CreateThread。请参见此处 - David Schwartz
@DavidSchwartz,CreateThread 不会创建线程池。 - Lubo Antonov
@lucas1024:线程池就是一组线程池。 - David Schwartz
1
@David:整个“池化”部分真的非常复杂和重要。 - Puppy
4个回答

4
这很简单,你需要一些类:
一个任务类(Task class),其中有一个“run”方法 - 这是供池用户重写以构建自己的任务的。
一个生产者-消费者(objectQueue)对象队列,线程在等待工作时使用。如果您有std::deque,则相对容易。如果没有,您将不得不编写自己的队列类型。除了队列类之外,您还需要其他同步内容,可能需要一个CriticalSection/Mutex来保护队列和一个semaphore供线程等待。
一个线程池(threadPool)类 - 包含P-C队列、submit(TaskClass aTask)方法和其他内容。
在threadPool constructor中创建一堆线程 - 使用CreateThread并将threadPool实例作为lpParam参数传递,这样线程可以将其转换回来以访问threadPool。
线程在threadPool->objectQueue上等待工作,例如:
// 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);
};

// C++

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

感谢Matrin提供了一个简单的线程池实现。在将新任务分配给线程池中的线程之前,我如何检查现有线程的状态? - Tariq

4

1


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接