asyncio-queue.md
1> **Источник:** https://python-all.ru/3/library/asyncio-queue.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Очереди89**Исходный код:** [Lib/asyncio/queues.py](https://python-all.ru/src/3.14/Lib/asyncio/queues.py)1011---1213Очереди asyncio разработаны по аналогии с классами [`queue`](https://python-all.ru/3/library/queue.html#module-queue) модуля. Хотя очереди asyncio не являются потокобезопасными, они предназначены для использования именно в async/await коде.1415Обратите внимание: методы очередей asyncio не имеют параметра *тайм-аут*; используйте функцию [`asyncio.wait_for()`](https://python-all.ru/3/library/asyncio-task.html#asyncio.wait_for) для выполнения операций с очередью с тайм-аутом.1617Смотрите также раздел [Примеры](https://python-all.ru/3/library/asyncio-queue.html#examples) ниже.1819## Очередь2021#### `class asyncio.Queue(maxsize=0)`2223Очередь «первым вошёл – первым вышел» (FIFO).2425Если *maxsize* меньше или равен нулю, размер очереди бесконечен. Если это целое число больше `0`, то `await put()` блокируется, когда очередь достигает *maxsize* пока элемент не будет удалён с помощью [`get()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.get).2627В отличие от [`queue`](https://python-all.ru/3/library/queue.html#module-queue) из стандартной библиотеки threading, размер очереди всегда известен и может быть получен вызовом метода [`qsize()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.qsize).2829Изменено в версии 3.10: Удалён параметр *loop*.3031This class is [не является потокобезопасным](https://python-all.ru/3/library/asyncio-dev.html#asyncio-multithreading).3233#### `maxsize`3435Количество элементов, которое может содержать очередь.3637#### `empty()`3839Возвращает `True`, если очередь пуста, иначе `False`.4041#### `full()`4243Возвращает `True`, если в очереди [`maxsize`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.maxsize) элементов.4445Если очередь была инициализирована с `maxsize=0` (по умолчанию), то `full()` никогда не возвращает `True`.4647#### `async get()`4849Удаляет элемент из очереди и возвращает его. Если очередь пуста, ожидает, пока элемент не станет доступен.5051Вызывает [`QueueShutDown`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.QueueShutDown), если очередь была закрыта и пуста, или если очередь была закрыта немедленно.5253#### `get_nowait()`5455Возвращает элемент, если он доступен немедленно, в противном случае вызывает [`QueueEmpty`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.QueueEmpty).5657#### `async join()`5859Блокирует выполнение до тех пор, пока все элементы в очереди не будут получены и обработаны.6061Счётчик незавершённых задач увеличивается при каждом добавлении элемента в очередь. Счётчик уменьшается, когда корутина-потребитель вызывает [`task_done()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.task_done), чтобы указать, что элемент был получен и вся работа над ним завершена. Когда счётчик незавершённых задач падает до нуля, `join()` разблокируется.6263#### `async put(item)`6465Помещает элемент в очередь. Если очередь заполнена, ожидает, пока не появится свободное место, прежде чем добавить элемент.6667Вызывает [`QueueShutDown`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.QueueShutDown), если очередь была закрыта.6869#### `put_nowait(item)`7071Помещает элемент в очередь без блокировки.7273Если свободный слот недоступен сразу, возбуждается исключение [`QueueFull`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.QueueFull).7475#### `qsize()`7677Возвращает количество элементов в очереди.7879#### `shutdown(immediate=False)`8081Переводит экземпляр `Queue` в режим завершения работы.8283Очередь больше не может расти. Последующие вызовы [`put()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.put) возбуждают исключение [`QueueShutDown`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.QueueShutDown). Текущие блокированные вызывающие `put()` будут разблокированы и возбудят исключение `QueueShutDown` в ранее ожидавшей задаче.8485Если *immediate* равен false (значение по умолчанию), очередь можно завершить нормально с помощью вызовов [`get()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.get) для извлечения задач, которые уже были загружены.8687И если [`task_done()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.task_done) вызывается для каждой оставшейся задачи, ожидающий вызов [`join()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.join) будет разблокирован нормально.8889Как только очередь опустеет, последующие вызовы [`get()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.get) будут возбуждать исключение [`QueueShutDown`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.QueueShutDown).9091Если *immediate* равен true, очередь завершается немедленно. Очередь опустошается полностью, и счётчик незавершённых задач уменьшается на количество извлечённых задач. Если незавершённых задач нет, вызывающие [`join()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.join) разблокируются. Также блокированные вызывающие [`get()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.get) разблокируются и возбудят исключение [`QueueShutDown`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.QueueShutDown), так как очередь пуста.9293Соблюдайте осторожность при использовании [`join()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.join) с параметром *immediate*, установленным в true. Это разблокирует join, даже если над задачами не было проделано никакой работы, нарушая обычный инвариант ожидания завершения очереди.9495Добавлено в версии 3.13.9697#### `task_done()`9899Указывает, что ранее помещённый в очередь элемент работы завершён.100101Используется потребителями очереди. Для каждого вызова [`get()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.get), использованного для извлечения элемента работы, последующий вызов `task_done()` сообщает очереди, что обработка элемента работы завершена.102103Если вызов [`join()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.join) в данный момент заблокирован, он возобновится, когда все элементы будут обработаны (то есть для каждого помещённого в очередь элемента [`put()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.put) был получен вызов `task_done()`).104105Возбуждает исключение [`ValueError`](https://python-all.ru/3/library/exceptions.html#ValueError), если вызывается больше раз, чем было помещено элементов в очередь.106107## Приоритетная очередь108109#### `class asyncio.PriorityQueue`110111Вариант [`Queue`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue); извлекает элементы в порядке приоритета (сначала наименьший).112113Элементы обычно представляют собой кортежи вида `(priority_number, data)`.114115## Очередь LIFO116117#### `class asyncio.LifoQueue`118119Вариант [`Queue`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue), который извлекает элементы, добавленные последними, в первую очередь (последним пришёл – первым ушёл).120121## Исключения122123#### `exception asyncio.QueueEmpty`124125Это исключение возбуждается, когда метод [`get_nowait()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.get_nowait) вызывается на пустой очереди.126127#### `exception asyncio.QueueFull`128129Исключение возбуждается, когда метод [`put_nowait()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.put_nowait) вызывается на очереди, достигшей своего *maxsize*.130131#### `exception asyncio.QueueShutDown`132133Исключение возбуждается, когда [`put()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.put) или [`get()`](https://python-all.ru/3/library/asyncio-queue.html#asyncio.Queue.get) вызывается на очереди, которая была завершена (shut down).134135Добавлено в версии 3.13.136137## Примеры138139Очереди можно использовать для распределения нагрузки между несколькими конкурентными задачами:140141```python142import asyncio143import random144import time145146async def worker(name, queue):147 while True:148 # Извлечь "рабочий элемент" из очереди.149 sleep_for = await queue.get()150151 # Подождать в течение "sleep_for" секунд.152 await asyncio.sleep(sleep_for)153154 # Уведомить очередь, что "рабочий элемент" обработан.155 queue.task_done()156157 print(f'{name} has slept for {sleep_for:.2f} seconds')158159async def main():160 # Создать очередь для хранения "рабочей нагрузки".161 queue = asyncio.Queue()162163 # Сгенерировать случайные задержки и поместить их в очередь.164 total_sleep_time = 0165 for _ in range(20):166 sleep_for = random.uniform(0.05, 1.0)167 total_sleep_time += sleep_for168 queue.put_nowait(sleep_for)169170 # Создать три рабочих задачи для параллельной обработки очереди.171 tasks = []172 for i in range(3):173 task = asyncio.create_task(worker(f'worker-{i}', queue))174 tasks.append(task)175176 # Ожидать полной обработки очереди.177 started_at = time.monotonic()178 await queue.join()179 total_slept_for = time.monotonic() - started_at180181 # Отменить наши рабочие задачи.182 for task in tasks:183 task.cancel()184 # Ожидать отмены всех рабочих задач.185 await asyncio.gather(*tasks, return_exceptions=True)186187 print('====')188 print(f'3 workers slept in parallel for {total_slept_for:.2f} seconds')189 print(f'total expected sleep time: {total_sleep_time:.2f} seconds')190191asyncio.run(main())192```193