Spec-Zone.ru › Python 3.13

Очередь — класс синхронизированной очереди

Исходный код: 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.

END_OF_DOCUMENT_MARKER

Объекты очереди

Объекты очереди (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).

См. также

Class multiprocessing.Queue

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

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

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

Spec-Zone.ru

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