Spec-Zone.ru › Python 3.12

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, который заполнен.

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

Объекты очереди (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 — истина и timeout — None, заблокировать, если необходимо, пока не появится свободное место. Если timeout — положительное число, он блокируется не более timeout секунд и поднимает исключение Full, если свободное место не было доступно в течение этого времени. В противном случае (block — ложь), поместить элемент в очередь, если свободное место сразу же доступно, иначе поднять исключение Full (timeout игнорируется в этом случае).

Queue.put_nowait(item)

Эквивалентно put(item, block=False).

Queue.get(block=True, timeout=None)

Удалить и вернуть элемент из очереди. Если необязательные аргументы block — истина и timeout — None, заблокировать, если необходимо, пока элемент не станет доступным. Если timeout — положительное число, он блокируется не более timeout секунд и поднимает исключение Empty, если элемент не был доступен в течение этого времени. В противном случае (block — ложь), вернуть элемент, если он доступен сразу же, иначе поднять исключение Empty (timeout игнорируется в этом случае).

До версии 3.0 на системах POSIX и для всех версий на Windows, если block — истина и timeout — None, эта операция переходит в непрерываемый ожидание на базовой блокировке. Это означает, что исключения не могут возникнуть, и в частности, SIGINT не вызовет KeyboardInterrupt.

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

Объекты 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–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/queue.html

Spec-Zone.ru

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