Как разблокировать все потоки, ожидающие семафор? - PullRequest
1 голос
/ 30 марта 2019

Я имею дело со стандартной проблемой производителя и потребителя с конечным массивом (или конечным числом буферов). Я попытался реализовать его с помощью семафоров, и я столкнулся с проблемой. Я хочу, чтобы продюсер «произвел» только 50 раз. После этого я хочу, чтобы продюсерский поток присоединился к основному. Эта часть проста, но я не могу присоединиться к потребительским потокам. Они застряли на семафоре, сигнализирующем об отсутствии данных. Как мне решить эту проблему?
Один из возможных вариантов - иметь переменную-флаг, которая становится Истиной, когда производитель присоединяется к основному, и после этого основной поток делает пост (семафор) столько раз, сколько число рабочих потоков. Рабочие потоки будут проверять переменную flag каждый раз после пробуждения, и если True, то выходят из функции.
Я думаю, что мой метод довольно неэффективен из-за большого количества вызовов после семафора. Было бы здорово, если бы я мог разблокировать все темы сразу!
Изменить: я пытался реализовать все, что я сказал, и это не работает из-за тупика

Ответы [ 2 ]

2 голосов
/ 31 марта 2019

Одним из вариантов является метод «отравленной таблетки». Предполагается, что вы знаете, сколько существует потребительских потоков. Если предположить, что есть N потребителей, то после того, как производитель сделал свое дело, он помещает N «ядовитых таблеток» в очередь. «Ядовитая таблетка» - это просто объект / значение, совместимое по типу с тем, что обычно производит производитель, но которое отличается от обычного объекта / значения.

Когда потребитель узнает, что он съел таблетку с ядом, он умирает. Проблема решена.

1 голос
/ 30 марта 2019

Я создавал потребительские структуры производителей на C ++ только в операционной системе FreeRTOS, так что имейте это в виду. Это был мой единственный опыт с многозадачностью. Я бы сказал, что в этой программе я использовал только одного производителя и одного потребителя. И я сделал многозадачность в LabView, но это немного отличается от того, что вы могли бы иметь, я думаю.

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

производитель может либо

  1. блокируется, пока в очереди не будет места для постановки в очередь,
  2. блокируется на определенный период времени и продолжается в другом месте, если время потрачено и не удалось поставить в очередь данные
  3. немедленно иди в другое место

Похоже, у вас есть порядок в очереди ...

Считыватели очереди могут иметь схожие три типа политик, по крайней мере, в FreeRTOS.

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

По-моему, вы выбрали неправильный подход со "многими семафорами" (???) То, что вам нужно, это структура очереди, в которую производитель вводит материал ... Затем потребители читают из очереди все, что они должны делать ... Если очередь пуста, вам нужна политика в отношении действий потоков чтения очереди. Выбор политики необходим также тем читателям очереди и читателям семафоров, что им следует делать, когда очередь пуста или если они не получили полученный семафор. Я бы не использовал семафоры для такого рода проблем ...

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

Но я думаю, что вы должны предоставить более подробную информацию о том, что вы пытаетесь сделать, особенно с потребительскими потоками, сколько потоков у вас есть, и на каком языке вы программируете и т.д. ...

...