Сообщение об окончании очереди

Я учусь использовать модуль Queue, и меня немного смущает вопрос о том, как можно заставить поток потребителя очереди узнать, что очередь полный. В идеале я хотел бы использовать get () из потока потребителя и вызвать его исключение, если очередь помечена как «выполнено». Есть ли лучший способ сообщить об этом, чем добавление часового значения для пометки последнего элемента в очереди?

9
задан intuited 31 August 2010 в 00:21
поделиться

2 ответа

Лучше всего сделать это так, чтобы сама очередь уведомляла клиента о том, что она достигла состояния «выполнено». Затем клиент может предпринять любое действие, которое необходимо.

То, что вы предложили; проверять очередь, чтобы убедиться, что это делается периодически, было бы крайне нежелательно. Опрос — это антипаттерн в многопоточном программировании, вы всегда должны использовать уведомления.

РЕДАКТИРОВАТЬ:
Итак, вы говорите, что сама очередь знает, что она «сделана» на основе некоторых критериев, и должна уведомить клиентов об этом факте. Я думаю, что вы правы, и лучший способ сделать это - бросить, когда клиент вызывает get(), а очередь находится в состоянии готовности. Если вы выбросите это, это сведет на нет необходимость в дозорном значении на стороне клиента. Внутри очередь может определить, что она «сделана» любым удобным для нее способом, например. очередь пуста, ее состояние было установлено как «выполнено» и т. д. Я не вижу необходимости в дозорном значении.

0
ответ дан 4 December 2019 в 08:49
поделиться

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

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

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

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

Итак, на практике:

  • если вы уверены, что используете только обычную очередь, просто отправьте по одному дозорному на поток.
  • Если вы используете PriorityQueue, убедитесь, что сигнализатор имеет самый низкий приоритет.
6
ответ дан 4 December 2019 в 08:49
поделиться
Другие вопросы по тегам:

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