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

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

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

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

Спасибо!


person Dan    schedule 04.06.2010    source источник
comment
Вы можете использовать Boost Thread, который поддерживает общий мьютекс. ссылка   -  person Kirill V. Lyadvinsky    schedule 04.06.2010


Ответы (2)


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

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

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

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

person Jorge Ferreira    schedule 04.06.2010
comment
Спасибо, это именно то, что я искал. - person Dan; 04.06.2010
comment
Вы можете сделать то же самое с семафорами. - person SigTerm; 04.06.2010

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

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

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

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

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

person Ralph Allan Rice    schedule 04.06.2010