Почему 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). Ваша проблема не в блокировании/неблокировании; это звучит как классический производитель-потребитель.