Очередь — класс синхронизированной очереди
Исходный код: Lib/queue.py
Модуль queue реализует очереди с множественным производством и множественным потреблением. Он особенно полезен в многопоточной программировании, когда информация должна безопасно обмениваться между несколькими потоками. Класс Queue в этом модуле реализует все необходимые семантики блокировки.
Модуль реализует три типа очередей, которые различаются только порядком извлечения элементов. В очереди FIFO первыми извлекаются элементы, добавленные первыми. В очереди LIFO первым извлекается последний добавленный элемент (работает как стек). В очереди с приоритетом элементы хранятся в отсортированном виде (используя модуль heapq) и первым извлекается элемент с наименьшим значением.
Внутренне эти три типа очередей используют блокировки для временного блокирования конкурирующих потоков; однако они не предназначены для обработки повторной входной обработки в рамках одного потока.
Кроме того, модуль реализует «простой» тип очереди FIFO, SimpleQueue, чья конкретная реализация обеспечивает дополнительные гарантии в обмен на меньший функционал.
Модуль queue определяет следующие классы и исключения:
-
class queue.Queue(maxsize=0) -
Конструктор для очереди FIFO. maxsize — целое число, устанавливающее верхнюю границу количества элементов, которые могут быть помещены в очередь. Вставка будет заблокирована, как только этот размер будет достигнут, до тех пор, пока элементы очереди не будут извлечены. Если maxsize меньше или равно нулю, размер очереди бесконечен.
-
class queue.LifoQueue(maxsize=0) -
Конструктор для очереди LIFO. maxsize — целое число, устанавливающее верхнюю границу количества элементов, которые могут быть помещены в очередь. Вставка будет заблокирована, как только этот размер будет достигнут, до тех пор, пока элементы очереди не будут извлечены. Если maxsize меньше или равно нулю, размер очереди бесконечен.
-
class queue.PriorityQueue(maxsize=0) -
Конструктор для очереди с приоритетом. maxsize — целое число, устанавливающее верхнюю границу количества элементов, которые могут быть помещены в очередь. Вставка будет заблокирована, как только этот размер будет достигнут, до тех пор, пока элементы очереди не будут извлечены. Если maxsize меньше или равно нулю, размер очереди бесконечен.
Элементы с наименьшим значением извлекаются первыми (элемент с наименьшим значением — это тот, который был бы возвращён функцией
min(entries)). Типичный формат элементов — кортеж в виде:(priority_number, data).Если элементы data не сравнимы, данные можно обернуть в класс, который игнорирует элемент данных и сравнивает только номер приоритета:
from dataclasses import dataclass, field from typing import Any @dataclass(order=True) class PrioritizedItem: priority: int item: Any=field(compare=False)
-
class queue.SimpleQueue -
Конструктор для неограниченной очереди FIFO. Простые очереди не имеют расширенного функционала, такого как отслеживание задач.
Добавлен в версии 3.7.
-
exception queue.Empty -
Исключение, генерируемое, когда вызывается неблокирующий метод
get()(илиget_nowait()) для объектаQueue, который пуст.
-
exception queue.Full -
Исключение, генерируемое, когда вызывается неблокирующий метод
put()(илиput_nowait()) для объектаQueue, который заполнен.
-
exception queue.ShutDown -
Исключение, генерируемое, когда вызываются методы
put()илиget()для объектаQueue, который был остановлен.Добавлен в версии 3.13.
Объекты очереди
Объекты очереди (Queue, LifoQueue или PriorityQueue) предоставляют описанные ниже общедоступные методы.
-
Queue.qsize() -
Возвращает приблизительный размер очереди. Обратите внимание, что qsize() > 0 не гарантирует, что последующий вызов get() не заблокируется, и qsize() < maxsize не гарантирует, что put() не заблокируется.
-
Queue.empty() -
Возвращает
True, если очередь пуста,Falseв противном случае. Если empty() возвращаетTrue, это не гарантирует, что последующий вызов put() не заблокируется. Аналогично, если empty() возвращаетFalse, это не гарантирует, что последующий вызов get() не заблокируется.
-
Queue.full() -
Возвращает
Trueесли очередь заполнена,Falseв противном случае. Если full() возвращаетTrue, это не гарантирует, что последующий вызов get() не заблокируется. Аналогично, если full() возвращаетFalse, это не гарантирует, что последующий вызов put() не заблокируется.
-
Queue.put(item, block=True, timeout=None) -
Поместить item в очередь. Если необязательный аргумент block равен True и timeout равен
None(по умолчанию), заблокировать, если необходимо, пока не освободится место. Если timeout — положительное число, то заблокировать не более чем на timeout секунд и выбросить исключениеFull, если место не освободилось в течение этого времени. В противном случае (block равен False), поместить элемент в очередь, если место сразу же доступно, иначе выбросить исключениеFull(timeout игнорируется в этом случае).Вызывает исключение
ShutDown, если очередь была закрыта.
-
Queue.put_nowait(item) -
Эквивалентно
put(item, block=False).
-
Queue.get(block=True, timeout=None) -
Удалить и вернуть элемент из очереди. Если необязательные аргументы block равны True и timeout равен
None(по умолчанию), заблокировать, если необходимо, пока элемент не станет доступен. Если timeout — положительное число, то заблокировать не более чем на timeout секунд и выбросить исключениеEmpty, если элемент не стал доступен в течение этого времени. В противном случае (block равен False), вернуть элемент, если он сразу же доступен, иначе выбросить исключениеEmpty(timeout игнорируется в этом случае).До версии 3.0 на системах POSIX и для всех версий на Windows, если block равен True и timeout равен
None, эта операция переходит в непрерываемый ожидание на базовом замке. Это означает, что исключения не могут возникнуть, и, в частности, SIGINT не вызоветKeyboardInterrupt.Вызывает исключение
ShutDown, если очередь была закрыта и пуста, или если очередь была закрыта немедленно.
-
Queue.get_nowait() -
Эквивалентно
get(False).
Два метода предлагаются для отслеживания того, были ли задачи, помещенные в очередь, полностью обработаны потоками-потребителями демонов.
-
Queue.task_done() -
Указывает, что ранее помещенная в очередь задача завершена. Используется потоками-потребителями очереди. Для каждого вызова
get()для извлечения задачи, последующий вызовtask_done()сообщает очереди, что обработка задачи завершена.Если
join()в настоящее время заблокирован, он возобновится, когда все элементы будут обработаны (что означает, что вызовtask_done()был получен для каждого элемента, который был помещен в очередьput()).shutdown(immediate=True)вызываетtask_done()для каждого оставшегося элемента в очереди.Вызывает исключение
ValueError, если оно вызвано большее количество раз, чем было помещено элементов в очередь.
-
Queue.join() -
Заблокировать, пока все элементы в очереди не будут получены и обработаны.
Счетчик незавершенных задач увеличивается при добавлении элемента в очередь. Счетчик уменьшается, когда поток-потребитель вызывает
task_done(), чтобы указать, что элемент был получен и вся работа над ним завершена. Когда счетчик незавершенных задач упадет до нуля,join()разблокируется.
Пример того, как дождаться завершения задач в очереди:
import threading
import queue
q = queue.Queue()
def worker():
while True:
item = q.get()
print(f'Working on {item}')
print(f'Finished {item}')
q.task_done()
# Turn-on the worker thread.
threading.Thread(target=worker, daemon=True).start()
# Send thirty task requests to the worker.
for item in range(30):
q.put(item)
# Block until all tasks are done.
q.join()
print('All work completed')
Закрытие очередей
Queue объекты могут быть настроены так, чтобы предотвратить дальнейшее взаимодействие путем их закрытия.
-
Queue.shutdown(immediate=False) -
Закрыть очередь, заставив
get()иput()вызвать исключениеShutDown.По умолчанию,
get()в закрытой очереди вызовет исключение только после того, как очередь станет пустой. Установите immediate в True, чтобы заставитьget()вызвать исключение немедленно.Все заблокированные вызывающие стороны
put()иget()будут разблокированы. Если immediate равно True, задача будет помечена как завершенная для каждого оставшегося элемента в очереди, что может разблокировать вызывающие стороныjoin().Добавлен в версии 3.13.
Объекты SimpleQueue
SimpleQueue объекты предоставляют описанные ниже публичные методы.
-
SimpleQueue.qsize() -
Возвращает приблизительный размер очереди. Обратите внимание, что qsize() > 0 не гарантирует, что последующий вызов get() не заблокируется.
-
SimpleQueue.empty() -
Возвращает
True, если очередь пуста,Falseв противном случае. Если empty() возвращаетFalse, это не гарантирует, что последующий вызов get() не заблокируется.
-
SimpleQueue.put(item, block=True, timeout=None) -
Поместить item в очередь. Метод никогда не блокируется и всегда выполняется успешно (за исключением потенциальных низкоуровневых ошибок, таких как невозможность выделения памяти). Необязательные аргументы block и timeout игнорируются и предоставляются только для совместимости с
Queue.put().Детали реализации CPython: Этот метод имеет реализацию на C, которая является реентерабельной. То есть вызов
put()илиget()может быть прерван другим вызовомput()в том же потоке без возникновения тупика или повреждения внутреннего состояния очереди. Это делает его подходящим для использования в деструкторах, таких как методы__del__илиweakrefобратные вызовы.
-
SimpleQueue.put_nowait(item) -
Эквивалентно
put(item, block=False), предоставлено для совместимости сQueue.put_nowait().
-
SimpleQueue.get(block=True, timeout=None) -
Удалить и вернуть элемент из очереди. Если необязательный аргумент block имеет значение true, а timeout имеет значение
None(по умолчанию), блокироваться до тех пор, пока элемент не станет доступным. Если timeout является положительным числом, блокируется не более timeout секунд, и возбуждается исключениеEmpty, если ни один элемент не был доступен в течение этого времени. В противном случае (block ложно), возвращает элемент, если он немедленно доступен, в противном случае возбуждает исключениеEmpty(timeout игнорируется в этом случае).
-
SimpleQueue.get_nowait() -
Эквивалентно
get(False).
См. также
-
Classmultiprocessing.Queue -
Класс очереди для использования в многопроцессной (а не многопоточной) среде.
collections.deque — это альтернативная реализация неограниченных очередей с быстрыми атомными операциями append() и popleft(), которые не требуют блокировок, а также поддерживают индексирование.
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/queue.html