2010-10-13 4 views
15

В среде выполнения параллелизма, представленной в VS2010, существует класс concurrent_queue. Он имеет функцию блокировки try_pop().
Как и в случае блоков Intel Thread Building Blocks (TBB), блокировка pop() была удалена при переходе от версии 2.1 в 2.2.Почему concurrent_queue не блокирует?

Интересно, в чем проблема с блокирующим вызовом. Почему он был удален из TBB? И почему нет блокировки concurrent_queue?

Я в ситуации, когда мне нужна блокирующая параллельная очередь, и я не хочу оживленного ожидания. Помимо написания очереди самостоятельно, есть ли другая возможность в среде выполнения параллелизма?

ответ

25

От a comment from Arch Robison, и он не получает гораздо больше "horse's mouth", чем (а):


ППЛ concurrent_queue не имеет блокировки поп, следовательно, ни один не делает tbb::strict_ppl::concurrent_queue. Блокирующий поп доступен в tbb::concurrent_bounded_queue.

Аргумент дизайна для исключения блокирующего поп-файла заключается в том, что во многих случаях синхронизация для блокировки предоставляется вне очереди, и в этом случае реализация блокировки внутри очереди становится ненужной служебной информацией.

С другой стороны, блокирующий поп старого tbb::concurrent_queue был популярен среди пользователей, у которых не было внешней синхронизации.

Итак, мы разделили функциональность. Случаи, которые не требуют блокировки или ограниченности, могут использовать новый tbb::concurrent_queue, а в случаях, когда это необходимо, можно использовать tbb::concurrent_bounded_queue.


(а) Arch является архитектором Threading Building Blocks.

4

Если вам нужен блокирующий поп без оживленного ожидания, вам нужен способ сигнализации. Это подразумевает синхронизацию между pusher и poper, а в очереди больше нет (дорогих) примитивов синхронизации. В основном вы получаете обычную синхронизированную очередь с переменной условия, используемой для уведомления попперсов толкателей, что не в духе коллекций concurrent_ *.

0

Нет ситуации, с точки зрения очереди, что она должна нужна для блокировки для вставки или удаления. Тот факт, что вам может понадобиться блокировать и ждать вставку, не имеет значения.

Вы можете достичь желаемой функциональности, используя переменную условия, или счетный семафор, или что-то в этом направлении (независимо от вашего конкретного API). Ваша проблема не в блокировании/неблокировании; это звучит как классический производитель-потребитель.

+2

с блокирующим 'pop', вы можете * реализовать *«классический производитель-потребитель»с использованием TBB примерно две строки кода, без необходимости писать какие-либо примитивы синхронизации самостоятельно. (Потребитель 'while (true) потребляет (Q.pop());' и производитель делает 'while (true) Q.push (product());'.) Без блокировки 'pop', та же проблема требуется как минимум в два раза больше кода, а именно, бухгалтерия - дополнительная переменная условия для каждой очереди. Но, как говорит paxdiablo, 'tbb :: concurrent_bounded_queue' продолжает обеспечивать блокирующую функцию' pop', и в основном является заменой замены для 'concurrent_queue'. – Quuxplusone

2

Вопрос в том, был ли еще один параметр в среде параллелизма, который обеспечивает функцию блокировки очереди, поскольку concurrent_queue не существует и в VS2010 есть один.

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

В VS2010 вы можете использовать класс шаблона unbounded_buffer, расположенный в, соответствующие методы называются enqueue и dequeue.

-Rick

Смежные вопросы