queue — класс синхронизированной очереди
Исходный код: 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()).Возбуждает исключение
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) -
Переводит экземпляр
Queueв режим отключения.Очередь больше не может увеличиваться. Последующие вызовы
put()возбуждают исключениеShutDown. Потоки, уже заблокированные при вызовеput(), будут разблокированы, и в ранее заблокированном потоке возникнет исключениеShutDown.Если immediate имеет значение false (по умолчанию), очередь можно штатно опустошить, вызывая
get()для извлечения уже помещённых в неё задач.Если для каждой оставшейся задачи вызвать
task_done(), ожидающий вызовjoin()будет штатно разблокирован.Когда очередь опустеет, последующие вызовы
get()будут возбуждать исключениеShutDown.Если immediate имеет значение true, очередь отключается немедленно. Она полностью опустошается, а счётчик незавершённых задач уменьшается на количество извлечённых задач. Если число незавершённых задач равно нулю, ожидающие вызовы
join()разблокируются. Кроме того, потоки, заблокированные при вызовеget(), разблокируются и получат исключениеShutDown, поскольку очередь пуста.Будьте осторожны при использовании
join()со значением 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 имеет значение false) возвращает элемент, если он доступен немедленно; иначе возбуждает исключениеEmpty(в этом случае аргумент timeout игнорируется).
-
SimpleQueue.get_nowait() -
Эквивалентен
get(False).
См. также
-
Classmultiprocessing.Queue -
Класс очереди для использования в многопроцессном (а не многопоточном) контексте.
collections.deque — это альтернативная реализация неограниченных очередей с быстрыми атомарными операциями append() и popleft(), для которых не требуется блокировка; кроме того, она поддерживает индексирование.
© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/queue.html