asyncio-queue.md
1> **Источник:** https://python-all.ru/3.7/library/asyncio-queue.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Очереди89Очереди asyncio разработаны по аналогии с классами [`queue`](https://python-all.ru/3.7/library/queue.html#module-queue) модуля. Хотя очереди asyncio не являются потокобезопасными, они предназначены для использования именно в async/await коде.1011Обратите внимание: методы очередей asyncio не имеют параметра *тайм-аут*; используйте функцию [`asyncio.wait_for()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.wait_for) для выполнения операций с очередью с тайм-аутом.1213Смотрите также раздел [Примеры](https://python-all.ru/3.7/library/asyncio-queue.html#examples) ниже.1415## Очередь1617#### `class asyncio.Queue(maxsize=0, *, loop=None)`1819Очередь «первым вошёл – первым вышел» (FIFO).2021Если *maxsize* меньше или равен нулю, размер очереди бесконечен. Если это целое число больше `0`, то `await put()` блокируется, когда очередь достигает *maxsize* пока элемент не будет удалён с помощью [`get()`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.Queue.get).2223В отличие от [`queue`](https://python-all.ru/3.7/library/queue.html#module-queue) из стандартной библиотеки threading, размер очереди всегда известен и может быть получен вызовом метода [`qsize()`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.Queue.qsize).2425This class is [не является потокобезопасным](https://python-all.ru/3.7/library/asyncio-dev.html#asyncio-multithreading).2627#### `maxsize`2829Количество элементов, которое может содержать очередь.3031#### `empty()`3233Возвращает `True`, если очередь пуста, иначе `False`.3435#### `full()`3637Возвращает `True`, если в очереди [`maxsize`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.Queue.maxsize) элементов.3839Если очередь была инициализирована с `maxsize=0` (по умолчанию), то [`full()`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.Queue.full) никогда не возвращает `True`.4041#### `coroutine get()`4243Удаляет элемент из очереди и возвращает его. Если очередь пуста, ожидает, пока элемент не станет доступен.4445#### `get_nowait()`4647Возвращает элемент, если он доступен немедленно, в противном случае вызывает [`QueueEmpty`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.QueueEmpty).4849#### `coroutine join()`5051Блокирует выполнение до тех пор, пока все элементы в очереди не будут получены и обработаны.5253Счётчик незавершённых задач увеличивается при каждом добавлении элемента в очередь. Счётчик уменьшается, когда корутина-потребитель вызывает [`task_done()`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.Queue.task_done), чтобы указать, что элемент был получен и вся работа над ним завершена. Когда счётчик незавершённых задач падает до нуля, [`join()`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.Queue.join) разблокируется.5455#### `coroutine put(item)`5657Помещает элемент в очередь. Если очередь заполнена, ожидает, пока не появится свободное место, прежде чем добавить элемент.5859#### `put_nowait(item)`6061Помещает элемент в очередь без блокировки.6263Если свободный слот недоступен сразу, возбуждается исключение [`QueueFull`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.QueueFull).6465#### `qsize()`6667Возвращает количество элементов в очереди.6869#### `task_done()`7071Указывает, что ранее поставленная в очередь задача завершена.7273Используется потребителями очереди. Для каждого вызова [`get()`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.Queue.get), используемого для получения задачи, последующий вызов [`task_done()`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.Queue.task_done) сообщает очереди, что обработка задачи завершена.7475Если вызов [`join()`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.Queue.join) в данный момент заблокирован, он возобновится, когда все элементы будут обработаны (то есть для каждого помещённого в очередь элемента [`put()`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.Queue.put) был получен вызов [`task_done()`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.Queue.task_done)).7677Возбуждает исключение [`ValueError`](https://python-all.ru/3.7/library/exceptions.html#ValueError), если вызывается больше раз, чем было помещено элементов в очередь.7879## Приоритетная очередь8081#### `class asyncio.PriorityQueue`8283Вариант [`Queue`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.Queue); извлекает элементы в порядке приоритета (сначала наименьший).8485Элементы обычно представляют собой кортежи вида `(priority_number, data)`.8687## Очередь LIFO8889#### `class asyncio.LifoQueue`9091Вариант [`Queue`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.Queue), который извлекает элементы, добавленные последними, в первую очередь (последним пришёл – первым ушёл).9293## Исключения9495#### `exception asyncio.QueueEmpty`9697Это исключение возбуждается, когда метод [`get_nowait()`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.Queue.get_nowait) вызывается на пустой очереди.9899#### `exception asyncio.QueueFull`100101Исключение возбуждается, когда метод [`put_nowait()`](https://python-all.ru/3.7/library/asyncio-queue.html#asyncio.Queue.put_nowait) вызывается на очереди, достигшей своего *maxsize*.102103## Примеры104105Очереди можно использовать для распределения нагрузки между несколькими конкурентными задачами:106107```python108import asyncio109import random110import time111112async def worker(name, queue):113 while True:114 # Извлечь "рабочий элемент" из очереди.115 sleep_for = await queue.get()116117 # Подождать в течение "sleep_for" секунд.118 await asyncio.sleep(sleep_for)119120 # Уведомить очередь, что "рабочий элемент" обработан.121 queue.task_done()122123 print(f'{name} has slept for {sleep_for:.2f} seconds')124125async def main():126 # Создать очередь для хранения "рабочей нагрузки".127 queue = asyncio.Queue()128129 # Сгенерировать случайные задержки и поместить их в очередь.130 total_sleep_time = 0131 for _ in range(20):132 sleep_for = random.uniform(0.05, 1.0)133 total_sleep_time += sleep_for134 queue.put_nowait(sleep_for)135136 # Создать три рабочих задачи для параллельной обработки очереди.137 tasks = []138 for i in range(3):139 task = asyncio.create_task(worker(f'worker-{i}', queue))140 tasks.append(task)141142 # Ожидать полной обработки очереди.143 started_at = time.monotonic()144 await queue.join()145 total_slept_for = time.monotonic() - started_at146147 # Отменить наши рабочие задачи.148 for task in tasks:149 task.cancel()150 # Ожидать отмены всех рабочих задач.151 await asyncio.gather(*tasks, return_exceptions=True)152153 print('====')154 print(f'3 workers slept in parallel for {total_slept_for:.2f} seconds')155 print(f'total expected sleep time: {total_sleep_time:.2f} seconds')156157asyncio.run(main())158```159