C ++ Пул потоков Windows (без поддержки / c ++ 11) - PullRequest
2 голосов
/ 03 апреля 2012

Есть ли способ создать пул потоков только с использованием функций C ++ или Windows C ++? У меня нет доступа к boost или любым библиотекам (я могу получить доступ к проекту кода, но не могу найти ничего, кроме unix), и мне трудно найти способ реализовать пул потоков.

Я использую VS2010, который еще не поддерживает многопоточность C ++ 11, поэтому я немного застрял!

Ответы [ 4 ]

3 голосов
/ 03 апреля 2012

Это довольно просто.Вам нужны некоторые классы:

Класс задач с методом run - что-то, что пользователь пула должен переопределить для создания своих собственных задач.

Объект-потребитель-потребитель для очереди, которую ожидают потокина работу.Если у вас есть std :: deque, это довольно просто.Если нет, вам придется кодировать свой собственный тип очереди.Как и класс очереди, вам потребуются другие вещи для синхронизации, может быть CriticalSection / Mutex для защиты очереди и семафор для потоков, ожидающих.

Класс threadPool - то, что содержит очередь ПК, отправьте(TaskClass aTask) и другие вещи.

Куча потоков, созданных в ctor-потоке - используйте 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);
};

// 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);
};
3 голосов
/ 03 апреля 2012

Если ваша цель - Windows Vista или более поздняя версия, вы можете использовать этот пул потоков: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686980%28v=vs.85%29.aspx

На странице также есть пример на C ++.

1 голос
1 голос
/ 03 апреля 2012

Существует API для управления пулами потоков, вот ссылка: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686766(v=vs.85).aspx. Возможно, вы захотите найти библиотеку, которая обертывает ее, хотя и сложная.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...