Threadpools - босс / работник против сверстников (рабочая группа) моделей - PullRequest
1 голос
/ 31 марта 2012

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

У меня есть ряд задач, которые необходимо выполнить для одного и того же набора данных.Вот некоторый простой psuedocode для того, как бы я посмотрел на решение этой проблемы:

data = [0 ... 999]
data_index = 0
data_size = 1000

tasks = [0 ... 99]
task_index = 0    

threads = [0 ... 31]

thread_function()
{
    while (true)
    {
        index = data_index++ (using atomics)
        if index > data_size
        {
            sync

            if thread_index == 0
            {
                data_index = 0
                task_index++
                sync
            }
            else
            {
                sync
            }
            continue
        }

        tasks[task_index](data[index])
    }
}

(Во-первых, кажется, что должен быть способ сделать это, используя только одну точку синхронизации, но я не уверен, что этовозможно?)

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

Последний вопрос касается синхронизации, барьера или переменной условия и почему?

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

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

1 Ответ

1 голос
/ 31 марта 2012

Я немного озадачен вашим описанием здесь, надеюсь, нижеприведенное относится к делу.

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

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

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

Управляющая логика и рабочее состояние поддерживаются «боссом» в обоих сценариях. Поскольку параллельная работа выполняется над задачей, «объект» «босс» обрабатывает задачу, в простой реализации этот «босс» блокируется до завершения задачи, позволяя вызвать следующего «босса» в очереди.

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

...