пул потоков, C ++ - PullRequest
2 голосов
/ 16 июня 2011

Я работаю над сетевой программой, использующей C ++, и я хотел бы реализовать пул потоков.Всякий раз, когда я получаю событие из приемного сокета, я помещаю данные в очередь в пуле потоков.Я думаю о создании 5 отдельных потоков и буду последовательно проверять очередь, чтобы увидеть, есть ли какие-нибудь входящие данные, которые нужно сделать.

Это довольно прямолинейная тема, но я не эксперт, поэтому мне хотелось бы услышать что-нибудь, что могло бы помочь реализовать это.

Пожалуйста, дайте мне знать любые учебные пособия или ссылки или проблемы, которые я должен знать.

Ответы [ 5 ]

4 голосов
/ 16 июня 2011

Используйте Boost.Asio , и каждый поток в пуле вызывает io_service::run().

Несколько тем могут вызывать io_service :: run () для установки пула потоки, из которых обработчики завершения может быть вызван. Этот подход может также использоваться с io_service :: post () для использования средство для выполнения любых вычислительных задачи в пуле потоков.

Обратите внимание, что все темы, которые присоединились пул io_service считаются эквивалентно, и io_service может распределить работу по ним в произвольная мода.

1 голос
/ 16 июня 2011

Прежде чем я начну.
Используйте boost :: threads

Если вы хотите знать, как это сделать с помощью pthread, вам необходимо использовать условные переменные pthread. Это позволяет вам приостанавливать потоки, ожидающие работы, без использования процессора.

Когда элемент работы добавляется в очередь, вы сигнализируете переменную условия, и одна переменная освобождается от переменной условия, что позволяет ему извлекать элемент из очереди. Когда поток завершает обработку рабочего элемента, он возвращается к условной переменной, чтобы дождаться следующей части работы.

Основной цикл для потоков в цикле должен выглядеть следующим образом;

ThreadWorkLoop()                   // The function that all the pool threads run. 
{
    while(poolRunnin)
    {
        WorkItem = getWorkItem(); // Get an item from the queue. This suspends until an item 
        WorkItem->run();          // is available then you can run it.
    }
}
GetWorkItem()
{
    Locker  lock(mutex);                // RAII: Lock/unlock mutex
    while(workQueue.size() == 0)
    {
        conditionVariable.wait(mutex);  // Waiting on a condition variable suspends a thread
    }                                   // until the condition variable is signalled.
                                        // Note: the mutex is unlocked while the thread is suspended
    return workQueue.popItem();
}
AddItemToQueue(item)
{
    Locker lock(mutex);
    workQueue.pushItem(item);
    conditionVariable.signal();        // Release a thread from the condition variable.
}
0 голосов
/ 16 июня 2011

Boost Asio - хорошее решение.

Но если вы не хотите использовать его (или не можете использовать его по каким-либо причинам), то вы, вероятно, захотите использовать реализацию на основе семафора.

Вы можете найти реализацию многопоточной очереди на основе семафоров, которые я использую здесь:

https://gist.github.com/482342

Причина использования семафоров заключается в том, что вы можете избежать непрерывного опроса рабочих потоков и вместо этого вызывать их в ОС, когда есть работа, которую нужно сделать.

0 голосов
/ 16 июня 2011

Вам понадобится мьютекс и условная переменная.Mutex защитит вашу очередь заданий, а при получении потоков добавит задание в очередь и будет сигнализировать переменную условия.Рабочие потоки будут ожидать переменную условия и проснутся, когда она получит сигнал.

0 голосов
/ 16 июня 2011

Получите поток приема, чтобы отправить данные в очередь, и 5 потоков вытолкнули его.Защитите очередь с помощью мьютекса и дайте им «бороться» за данные.

Вы также хотите использовать usleep () или pthread_yield () в основном цикле рабочего потока

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