2013-09-17 9 views
0

дизайн ПрименениеSignaling между нитями

У меня есть C++ приложение, которое имеет производитель нить, несколько очередей (созданные во время выполнения) и потребительского потока.

Проводник получает данные через Tcp/Ip и помещается в соответствующую очередь (например, если данные являются типом A и помещены в очередь A).

Потребительский поток в настоящее время перемещает очереди от 1 до n для обработки данных из каждой очереди.

В соответствии с требованием нет необходимости отслеживать последнюю обновленную или последнюю очередь. До тех пор, пока какая-либо очередь обновляется, потребитель должен обработать из 1 - n очередей.

Если какой-либо размер очередей превышает установленный предел, поток производителя будет выталкивать первый элемент, прежде чем он вставляет новый элемент (для управления размером очереди).

синхронизация ресурсов и сигнализация между потоками:

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

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

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

Издание:

Давайте этот сценарий, рассмотрим потребитель обрабатывает данные N-й очереди в; в то же время производитель может помещать данные в очередь n-1, n-2, а сигнализация не эффективна, так как потребитель бодрствует и обрабатывает n-ые данные. Как только потребитель завершит обработку n-й очереди данных, он будет спать, а данные в n-1, n-2 не будут обрабатываться до тех пор, пока слушатель не получит какой-либо дополнительный сигнал.

Как мы можем решить этот сценарий? Люди также советуют использовать semophore. Семафор относится к этому сценарию?

Заранее спасибо.

+0

Как вы думаете? Какое ваше решение? – HAL

+0

Возможно, семафора будет недостаточно, поскольку comsumer по-прежнему не получает информацию для повторного сканирования на измененных/вставленных элементах. Он просто получает знак hios: его твой ход. Вы можете играть с общей переменной, которая читается каждым пользователем каждый раз, она заканчивает элемент очереди (пусть говорят последним), а затем проверяет переменную, которая была установлена ​​производителем, чтобы она должна была СТАВКА проверить очередь из начало. Если это так, то, что вам может понадобиться, – icbytes

ответ

3

Это классический пример для C++ 11 std::condition_variable.

Условие в этом случае - доступность расходных ресурсов. Если потребительский поток заканчивается, он wait с переменной состояния, которая эффективно усыпляет его. Изготовитель notify s после каждой вставки в очередь. Необходимо проявлять осторожность, чтобы организовать блокировку таким образом, чтобы соперничество в очередях было минимальным, но при этом избегайте сценария, когда потребитель пропускает уведомление и уходит спать, хотя работа доступна.

1

Семафор будет работать, да.

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

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

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

0

Вы можете использовать select и ждать с ним на файловый дескриптор, изготовленного из сигнала -> поэтому он может ждать тайм-аута (выбрать есть их) и просыпаются при приеме сигнала (сигнал должен быть замаскирован & заблокирован). Когда signalfd (смотрите man signalfd) можно прочитать, вы можете прочитать из него struct signalfd_siginfo и отметьте ssi_signo для номера сигнала (если это тот, который вы используете для связи).