> **Источник:** https://python-all.ru/3.12/library/asyncio-queue.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# Очереди

**Исходный код:** [Lib/asyncio/queues.py](https://python-all.ru/src/3.12/Lib/asyncio/queues.py)

---

Очереди asyncio разработаны по аналогии с классами [`queue`](https://python-all.ru/3.12/library/queue.html#module-queue) модуля. Хотя очереди asyncio не являются потокобезопасными, они предназначены для использования именно в async/await коде.

Обратите внимание: методы очередей asyncio не имеют параметра *тайм-аут*; используйте функцию [`asyncio.wait_for()`](https://python-all.ru/3.12/library/asyncio-task.html#asyncio.wait_for) для выполнения операций с очередью с тайм-аутом.

Смотрите также раздел [Примеры](https://python-all.ru/3.12/library/asyncio-queue.html#examples) ниже.

## Очередь

#### `class asyncio.Queue(maxsize=0)`

Очередь «первым вошёл – первым вышел» (FIFO).

Если *maxsize* меньше или равен нулю, размер очереди бесконечен. Если это целое число больше `0`, то `await put()` блокируется, когда очередь достигает *maxsize* пока элемент не будет удалён с помощью [`get()`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.Queue.get).

В отличие от [`queue`](https://python-all.ru/3.12/library/queue.html#module-queue) из стандартной библиотеки threading, размер очереди всегда известен и может быть получен вызовом метода [`qsize()`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.Queue.qsize).

Изменено в версии 3.10: Удалён параметр *loop*.

This class is [не является потокобезопасным](https://python-all.ru/3.12/library/asyncio-dev.html#asyncio-multithreading).

#### `maxsize`

Количество элементов, которое может содержать очередь.

#### `empty()`

Возвращает `True`, если очередь пуста, иначе `False`.

#### `full()`

Возвращает `True`, если в очереди [`maxsize`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.Queue.maxsize) элементов.

Если очередь была инициализирована с `maxsize=0` (по умолчанию), то [`full()`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.Queue.full) никогда не возвращает `True`.

#### `async get()`

Удаляет элемент из очереди и возвращает его. Если очередь пуста, ожидает, пока элемент не станет доступен.

#### `get_nowait()`

Возвращает элемент, если он доступен немедленно, в противном случае вызывает [`QueueEmpty`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.QueueEmpty).

#### `async join()`

Блокирует выполнение до тех пор, пока все элементы в очереди не будут получены и обработаны.

Счётчик незавершённых задач увеличивается при каждом добавлении элемента в очередь. Счётчик уменьшается, когда корутина-потребитель вызывает [`task_done()`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.Queue.task_done), чтобы указать, что элемент был получен и вся работа над ним завершена. Когда счётчик незавершённых задач падает до нуля, [`join()`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.Queue.join) разблокируется.

#### `async put(item)`

Помещает элемент в очередь. Если очередь заполнена, ожидает, пока не появится свободное место, прежде чем добавить элемент.

#### `put_nowait(item)`

Помещает элемент в очередь без блокировки.

Если свободный слот недоступен сразу, возбуждается исключение [`QueueFull`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.QueueFull).

#### `qsize()`

Возвращает количество элементов в очереди.

#### `task_done()`

Указывает, что ранее помещённый в очередь элемент работы завершён.

Используется потребителями очереди. Для каждого вызова [`get()`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.Queue.get), использованного для извлечения элемента работы, последующий вызов [`task_done()`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.Queue.task_done) сообщает очереди, что обработка элемента работы завершена.

Если вызов [`join()`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.Queue.join) в данный момент заблокирован, он возобновится, когда все элементы будут обработаны (то есть для каждого помещённого в очередь элемента [`put()`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.Queue.put) был получен вызов [`task_done()`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.Queue.task_done)).

Возбуждает исключение [`ValueError`](https://python-all.ru/3.12/library/exceptions.html#ValueError), если вызывается больше раз, чем было помещено элементов в очередь.

## Приоритетная очередь

#### `class asyncio.PriorityQueue`

Вариант [`Queue`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.Queue); извлекает элементы в порядке приоритета (сначала наименьший).

Элементы обычно представляют собой кортежи вида `(priority_number, data)`.

## Очередь LIFO

#### `class asyncio.LifoQueue`

Вариант [`Queue`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.Queue), который извлекает элементы, добавленные последними, в первую очередь (последним пришёл – первым ушёл).

## Исключения

#### `exception asyncio.QueueEmpty`

Это исключение возбуждается, когда метод [`get_nowait()`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.Queue.get_nowait) вызывается на пустой очереди.

#### `exception asyncio.QueueFull`

Исключение возбуждается, когда метод [`put_nowait()`](https://python-all.ru/3.12/library/asyncio-queue.html#asyncio.Queue.put_nowait) вызывается на очереди, достигшей своего *maxsize*.

## Примеры

Очереди можно использовать для распределения нагрузки между несколькими конкурентными задачами:

```python
import asyncio
import random
import time

async def worker(name, queue):
    while True:
        # Извлечь "рабочий элемент" из очереди.
        sleep_for = await queue.get()

        # Подождать в течение "sleep_for" секунд.
        await asyncio.sleep(sleep_for)

        # Уведомить очередь, что "рабочий элемент" обработан.
        queue.task_done()

        print(f'{name} has slept for {sleep_for:.2f} seconds')

async def main():
    # Создать очередь для хранения "рабочей нагрузки".
    queue = asyncio.Queue()

    # Сгенерировать случайные задержки и поместить их в очередь.
    total_sleep_time = 0
    for _ in range(20):
        sleep_for = random.uniform(0.05, 1.0)
        total_sleep_time += sleep_for
        queue.put_nowait(sleep_for)

    # Создать три рабочих задачи для параллельной обработки очереди.
    tasks = []
    for i in range(3):
        task = asyncio.create_task(worker(f'worker-{i}', queue))
        tasks.append(task)

    # Ожидать полной обработки очереди.
    started_at = time.monotonic()
    await queue.join()
    total_slept_for = time.monotonic() - started_at

    # Отменить наши рабочие задачи.
    for task in tasks:
        task.cancel()
    # Ожидать отмены всех рабочих задач.
    await asyncio.gather(*tasks, return_exceptions=True)

    print('====')
    print(f'3 workers slept in parallel for {total_slept_for:.2f} seconds')
    print(f'total expected sleep time: {total_sleep_time:.2f} seconds')

asyncio.run(main())
```
