Spec-Zone.ru › Python 3.10

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)

Поместить элемент в очередь. Метод никогда не блокируется и всегда выполняется успешно (за исключением потенциальных ошибок низкого уровня, таких как невозможность выделения памяти). Необязательные аргументы 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–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.10/library/queue.html

Spec-Zone.ru

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