2014-01-23 3 views
12

как я могу сделать поток в очереди безопасным? Мне нужно нажать/pop/front/back и очистить. есть что-то подобное в boost?является std :: queue thread safe с производителем и несколькими потребителями

У меня есть один производитель и один или несколько потребителей.

+0

Изучите [мьютексы] (http://vichargrave.com/multithreaded-work-queue-in-c/). – Martol1ni

+1

Ваше имя спрашивает, являются ли они потокобезопасными, но ваше вступительное предложение спрашивает, как вы можете их сделать. Значит, вы уже знаете ответ на вопрос в названии. – WhozCraig

+0

Возможный дубликат: C++ 11 поточно-безопасная очередь (http://stackoverflow.com/questions/15278343/c11-thread-safe-queue) – yasouser

ответ

1

Вы должны защитить доступ к std::queue. Если вы используете boost, защитите его, используя boost::mutex. Теперь, если у вас есть несколько читателей и один писательский поток, посмотрите на boost::shared_lock (для читателей) и boost::unique_lock (для писателя).

Однако, если вы столкнетесь с голосом писателя, посмотрите на boost::shared_mutex.

+2

Я сомневаюсь, что несколько читателей могут читать очередь одновременно и безопасно. По этому вопросу я считаю, что читатель вылетает из очереди. Поп-операция изменяет очередь и поэтому должна содержать исключительную блокировку в очереди. В других контекстах слово «читатель» используется для обозначения кода, который не выполняет никаких изменений и просто смотрит на значения. Если в этом вопросе читатели вызывают peek вместо pop, они удовлетворяют этим критериям, и совместные блокировки будут работать. – Jason

+0

@Jason, одно из возможных решений может быть измененным флагом-членом с атомарным механизмом CAS, который позволяет каждому потоку считывателя обрабатывать один уникальный элемент в очереди без всплытия, а периодическая фаза очистки (под исключительной блокировкой) может помочь очистить обработанных элементов. – Fox

0

Вы должны защитить его, например. с std::mutex, на каждые операции. Boost будет альтернативой, если у вас еще нет C++ 11.

+2

Несмотря на это, потребуется некоторая дополнительная синхронизация (скажем, вы хотите проверить, что очередь не пуста до появления. Это не является атомарным, поэтому может произойти сбой, даже если отдельные операции синхронизируются). – juanchopanza

9

std::queue не является потокобезопасным при написании одного или нескольких потоков. И его интерфейс не способствует реалистичной реализации потока, поскольку он имеет отдельные методы, такие как pop(), size() и empty(), которые необходимо синхронизировать извне.

Общепринятый подход * - реализовать тип очереди с более простым интерфейсом и использовать внутренние механизмы блокировки для обеспечения синхронизации.

* Поиск «параллельной очереди C++» должен давать много результатов. Я реализовал очень простую игрушку here, где ограничение заключалось в использовании только стандартного C++. См. Также книгу Энтони Уильямса Совместимость C++ в действии, а также его блог.

+0

Спасибо за ссылку! Очень приятное объяснение. – ikku100

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