Я учусь использовать модуль Queue, и меня немного смущает вопрос о том, как можно заставить поток потребителя очереди узнать, что очередь полный. В идеале я хотел бы использовать get ()
из потока потребителя и вызвать его исключение, если очередь помечена как «выполнено». Есть ли лучший способ сообщить об этом, чем добавление часового значения для пометки последнего элемента в очереди?
Лучше всего сделать это так, чтобы сама очередь уведомляла клиента о том, что она достигла состояния «выполнено». Затем клиент может предпринять любое действие, которое необходимо.
То, что вы предложили; проверять очередь, чтобы убедиться, что это делается периодически, было бы крайне нежелательно. Опрос — это антипаттерн в многопоточном программировании, вы всегда должны использовать уведомления.
РЕДАКТИРОВАТЬ:
Итак, вы говорите, что сама очередь знает, что она «сделана» на основе некоторых критериев, и должна уведомить клиентов об этом факте. Я думаю, что вы правы, и лучший способ сделать это - бросить, когда клиент вызывает get(), а очередь находится в состоянии готовности. Если вы выбросите это, это сведет на нет необходимость в дозорном значении на стороне клиента. Внутри очередь может определить, что она «сделана» любым удобным для нее способом, например. очередь пуста, ее состояние было установлено как «выполнено» и т. д. Я не вижу необходимости в дозорном значении.
Страж — это естественный способ закрыть очередь, но есть несколько моментов, на которые следует обратить внимание.
Во-первых, помните, что у вас может быть более одного потребителя, поэтому вам нужно отправить дозорный сигнал один раз для каждого работающего потребителя и гарантировать, что каждый потребитель будет потреблять только один дозорный, чтобы гарантировать, что каждый потребитель получит свое дозорное отключение.
Во-вторых, помните, что Queue определяет интерфейс, и что, когда это возможно, код должен вести себя независимо от базовой очереди. У вас может быть PriorityQueue или другой класс, предоставляющий тот же интерфейс и возвращающий значения в другом порядке.
К сожалению, трудно иметь дело с обоими из них. Чтобы иметь дело с общим случаем различных очередей, завершающийся потребитель должен продолжать потреблять значения после получения сигнала о завершении работы до тех пор, пока очередь не станет пустой. Это означает, что он может потреблять часовой другой поток. Это недостаток интерфейса Queue: он должен иметь вызов Queue.shutdown
, чтобы вызвать исключение для всех потребителей, но он отсутствует.
Итак, на практике: