Spec-Zone.ru › Python 3.9

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 меньше или равно нулю, размер очереди бесконечен.

Элементы с наименьшими значениями извлекаются первыми (элемент с наименьшим значением — тот, который возвращает sorted(list(entries))[0]). Типичный шаблон для записей — кортеж в форме: (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, 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)
print('All task requests sent\n', end='')

# 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–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.9/library/queue.html

Spec-Zone.ru

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