#c #multithreading #c 11 #queue #message-queue
#c #многопоточность #c 11 #очередь #очередь сообщений
Вопрос:
Существует ли какой-либо механизм событий или предопределенные сигналы в очереди. Если в очередь поступают какие-либо данные или сообщение, очередь должна сгенерировать событие, в котором говорится, что данные готовы к обработке. Или сигнализируйте другому потоку о выполнении его задачи вместо непрерывного опроса очереди.
В очереди сообщений posix есть функция like mq_notify()
, которая уведомляет другой процесс или поток, если какие-либо данные поступают в очередь сообщений, чтобы мы могли избежать опроса.
Редактировать
Если нет, то как я могу добиться этого на std::queue
. Я хочу избежать непрерывного опроса, который замедляет производительность кода.
Всякий раз, когда в очереди происходит какое-либо событие, оно должно уведомлять других.
Комментарии:
1. std::deque не предназначен для использования непосредственно с потоками. вы должны выполнить синхронизацию самостоятельно, включая передачу сигналов.
2. @DonReba — поддерживаются ли очереди TBB процессором AMD.
3. @ali786, TBB (блоки построения потоков) является кроссплатформенным.
4. @DonReba спасибо, я думал, что они зависят от архитектуры и могут быть выполнены только на процессорах Intel с потоковой передачей.
5. Это работает для широкого спектра процессоров, включая AMD.
Ответ №1:
std::queue — это тип контейнера, а не механизм событий. Я рекомендую создать класс вокруг очереди, который реализует очередь сообщений.
РЕДАКТИРОВАТЬ: Хорошо, итак
Поэтому я рекомендую использовать std::queue, std::mutex и std::condition_variable, если вы используете boost, который имеет те же типы. Помещая их в свой новый класс Queue и при нажатии, вы бы заблокировали мьютекс, переместили в очередь, разблокировали мьютекс и уведомили бы об этом условие.() Таким образом, переменная условия уведомляется только при нажатии. Вы можете сделать то же самое в pop.
Комментарии:
1. какая очередь сообщений posix или BSD, очередь сообщений Posix имеет механизм событий.
2. Не могли бы вы уточнить, что мне следует делать.
Ответ №2:
К этому есть два подхода. Проще всего иметь асинхронную очередь, реализованную с использованием мьютекса и переменной условия, в которой поток блокируется, ожидая, пока другой поток отправит что-то в очередь. Это очень распространенная идиома для диспетчеризации задач, и вот две простые реализации:
http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html и http://cxx-gtk-utils.sourceforge.net/2.2/classCgu_1_1AsyncQueueDispatch.html
Используя список, а не deque в качестве контейнера очереди, вы можете выделять новые узлы вне мьютекса очереди, что значительно повышает производительность при высокой конкуренции (см. Исходный код для второй ссылки, упомянутой выше, для примера использования std::list::splice для достижения этой цели).
Вместо того, чтобы иметь назначенный блок потока в асинхронной очереди, после того, как поток помещает элемент в очередь, он может вместо этого вызвать событие в цикле событий программы, который выполняет обратный вызов, который извлекает элемент из очереди и что-то с ним делает. Реализация этого более специфична для ОС, но см.http://www.appinf.com/docs/poco/Poco .NotificationQueue.html и http://cxx-gtk-utils.sourceforge.net/2.2/classCgu_1_1Notifier.html для разных подходов к этому.