Spec-Zone.ru › Python 3.13

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).

См. также

Class multiprocessing.Queue

Класс очереди для использования в многопроцессном (а не многопоточном) контексте.

collections.deque — это альтернативная реализация неограниченных очередей с быстрыми атомарными операциями append() и popleft(), для которых не требуется блокировка; кроме того, она поддерживает индексирование.

© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/queue.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API