Почему concurrent_queue не блокирует?

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

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

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

Ответы

Ответ 1

Из комментарий от Arch Robison, и он не получает гораздо больше "лошадиный рот" , чем (a):


PPL concurrent_queue не имеет блокировки, поэтому не имеет значения tbb::strict_ppl::concurrent_queue. Блокирующий поп доступен в tbb::concurrent_bounded_queue.

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

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

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


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

Ответ 2

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

Ответ 3

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

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

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

-Rick

Ответ 4

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

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