C++: синхронизируйте 5 потребителей с 1 (многопоточным) производителем

У меня есть пять потребителей и один производитель. Эти пять потребителей каждый вывод различные данные, от одного производителя, для ~10ms. Во время тех 10 мс производитель готовит параметры к следующему выводу. Когда выходные параметры установлены, я хочу установить флаг, дающий потребителям команду начать следующий вывод. Я только хочу, чтобы производитель произвел, когда потребители производят данные.

Я не уверен, как синхронизировать эти пять потребителей и единственного производителя. У меня в настоящее время есть два флага, runFlag и doneFlag. Когда потребитель считывает новые данные, я хочу установить runFlag на истинный, таким образом, вычисления начинаются, и я хочу установить doneFlag на ложь, поскольку вычисления не завершились. Однако, если я установил doneFlag на ложь в одном потребителе, это может быть ложь в другом потребителе, прежде чем тот потребитель сможет проверить флаг.

Я надеюсь, что мой вопрос достаточно конкретен. Сообщите мне, существует ли что-либо еще, что я могу обеспечить. Кроме того, я просто ищу общее представление о том, как продолжить двигаться. Я знаю, что существует несколько способов сделать это, но я не уверен, какой метод будет работать лучшее.

Спасибо!

1
задан Dan 4 June 2010 в 16:37
поделиться

2 ответа

Вам потребуются 2 события и целочисленный счетчик ссылок.

Когда производитель что-то произвел, он:

  • инициирует read_count = 0;
  • устанавливает событие readme .
  • начинает ожидать завершения события,

Потребители ожидают события , readme . После выполнения своей работы они АТОМИЧЕСКИ увеличивают read_count . Если read_count достигает количества потребителей, в вашем случае 5, тогда он устанавливает событие completed . Таким образом, производитель может продолжить, и цикл повторяется.

2
ответ дан 3 September 2019 в 00:03
поделиться

Несколько лет назад мне пришлось создать общий диспетчер работ, который выполняет постобработку. Это точно не производитель-потребитель и может быть излишним для вашего приложения, но он может дать вам некоторые идеи.

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

Ваши данные, известные производителю и потребителю, на которые есть ссылка в классе рабочего элемента. Класс рабочего элемента содержит все флаги состояния. Данные также должны быть потокобезопасными.

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

IIRC, архитектура содержит только три класса или около того.

0
ответ дан 3 September 2019 в 00:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: