boost::thread_group — можно ли вызывать create_thread после join_all?

StackOverflow https://stackoverflow.com/questions/2290306

Вопрос

У меня следующая ситуация:

Я создаю экземпляр boost::thread_group, затем создаю потоки для параллельной обработки некоторых данных, а затем join_all для потоков.

Первоначально я создал потоки для каждого X элементов данных, например:

// begin = someVector.begin();
// end = someVector.end();
// batchDispatcher = boost::function<void(It, It)>(...);

boost::thread_group     processors;

// create dispatching thread every ASYNCH_PROCESSING_THRESHOLD notifications
while(end - begin > ASYNCH_PROCESSING_THRESHOLD)
{
    NotifItr split = begin + ASYNCH_PROCESSING_THRESHOLD;

    processors.create_thread(boost::bind(batchDispatcher, begin, split));
    begin = split;
}

// create dispatching thread for the remainder
if(begin < end)
{
    processors.create_thread(boost::bind(batchDispatcher, begin, end));
}

// wait for parallel processing to finish
processors.join_all();

но у меня проблема с этим:Когда у меня много данных, этот код генерирует много потоков (> 40 потоков), что заставляет процессор работать с контекстами переключения потоков.

Мой вопрос заключается в следующем:Можно ли вызвать create_thread в thread_group? после вызов join_all.

То есть могу ли я изменить свой код на этот?

boost::thread_group     processors;
size_t                  processorThreads = 0; // NEW CODE

// create dispatching thread every ASYNCH_PROCESSING_THRESHOLD notifications
while(end - begin > ASYNCH_PROCESSING_THRESHOLD)
{
    NotifItr split = begin + ASYNCH_PROCESSING_THRESHOLD;

    processors.create_thread(boost::bind(batchDispatcher, begin, split));
    begin = split;

    if(++processorThreads >= MAX_ASYNCH_PROCESSORS) // NEW CODE
    {                               // NEW CODE
        processors.join_all();      // NEW CODE
        processorThreads = 0;       // NEW CODE
    }                               // NEW CODE
}

// ... 

Кто сталкивался с этим, спасибо за любую информацию.

Это было полезно?

Решение

Я считаю, что это невозможно.Решение, которое вы хотите, на самом деле может заключаться в реализации производитель-потребитель или главный-работник (основной «главный» поток делит работу на несколько задач фиксированного размера, создает пул «рабочих» потоков и отправляет по одной задаче каждому работнику, пока все задачи не будут выполнены).

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

Еще один не очень хороший и необычный вариант — присоединяться к одному потоку за раз.Вы можете иметь вектор с 4 активными потоками, присоединяться к одному и создавать другой.Проблема этого подхода в том, что вы можете тратить время на обработку, если ваши задачи неоднородны.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top