Документация Python неофициальный перевод

asyncio-queue.md

165 строк · 9.9 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.8/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.8/Lib/asyncio/queues.py)1011---1213Очереди asyncio разработаны по аналогии с классами [`queue`](https://python-all.ru/3.8/library/queue.html#module-queue) модуля. Хотя очереди asyncio не являются потокобезопасными, они предназначены для использования именно в async/await коде.1415Обратите внимание: методы очередей asyncio не имеют параметра *тайм-аут*; используйте функцию [`asyncio.wait_for()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.wait_for) для выполнения операций с очередью с тайм-аутом.1617Смотрите также раздел [Примеры](https://python-all.ru/3.8/library/asyncio-queue.html#examples) ниже.1819## Очередь2021#### `class asyncio.Queue(maxsize=0, *, loop=None)`2223Очередь «первым вошёл – первым вышел» (FIFO).2425Если *maxsize* меньше или равен нулю, размер очереди бесконечен. Если это целое число больше `0`, то `await put()` блокируется, когда очередь достигает *maxsize* пока элемент не будет удалён с помощью [`get()`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.Queue.get).2627В отличие от [`queue`](https://python-all.ru/3.8/library/queue.html#module-queue) из стандартной библиотеки threading, размер очереди всегда известен и может быть получен вызовом метода [`qsize()`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.Queue.qsize).2829Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.3031This class is [не является потокобезопасным](https://python-all.ru/3.8/library/asyncio-dev.html#asyncio-multithreading).3233#### `maxsize`3435Количество элементов, которое может содержать очередь.3637#### `empty()`3839Возвращает `True`, если очередь пуста, иначе `False`.4041#### `full()`4243Возвращает `True`, если в очереди [`maxsize`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.Queue.maxsize) элементов.4445Если очередь была инициализирована с `maxsize=0` (по умолчанию), то [`full()`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.Queue.full) никогда не возвращает `True`.4647#### `coroutine get()`4849Удаляет элемент из очереди и возвращает его. Если очередь пуста, ожидает, пока элемент не станет доступен.5051#### `get_nowait()`5253Возвращает элемент, если он доступен немедленно, в противном случае вызывает [`QueueEmpty`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.QueueEmpty).5455#### `coroutine join()`5657Блокирует выполнение до тех пор, пока все элементы в очереди не будут получены и обработаны.5859Счётчик незавершённых задач увеличивается при каждом добавлении элемента в очередь. Счётчик уменьшается, когда корутина-потребитель вызывает [`task_done()`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.Queue.task_done), чтобы указать, что элемент был получен и вся работа над ним завершена. Когда счётчик незавершённых задач падает до нуля, [`join()`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.Queue.join) разблокируется.6061#### `coroutine put(item)`6263Помещает элемент в очередь. Если очередь заполнена, ожидает, пока не появится свободное место, прежде чем добавить элемент.6465#### `put_nowait(item)`6667Помещает элемент в очередь без блокировки.6869Если свободный слот недоступен сразу, возбуждается исключение [`QueueFull`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.QueueFull).7071#### `qsize()`7273Возвращает количество элементов в очереди.7475#### `task_done()`7677Указывает, что ранее поставленная в очередь задача завершена.7879Используется потребителями очереди. Для каждого вызова [`get()`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.Queue.get), используемого для получения задачи, последующий вызов [`task_done()`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.Queue.task_done) сообщает очереди, что обработка задачи завершена.8081Если вызов [`join()`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.Queue.join) в данный момент заблокирован, он возобновится, когда все элементы будут обработаны (то есть для каждого помещённого в очередь элемента [`put()`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.Queue.put) был получен вызов [`task_done()`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.Queue.task_done)).8283Возбуждает исключение [`ValueError`](https://python-all.ru/3.8/library/exceptions.html#ValueError), если вызывается больше раз, чем было помещено элементов в очередь.8485## Приоритетная очередь8687#### `class asyncio.PriorityQueue`8889Вариант [`Queue`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.Queue); извлекает элементы в порядке приоритета (сначала наименьший).9091Элементы обычно представляют собой кортежи вида `(priority_number, data)`.9293## Очередь LIFO9495#### `class asyncio.LifoQueue`9697Вариант [`Queue`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.Queue), который извлекает элементы, добавленные последними, в первую очередь (последним пришёл – первым ушёл).9899## Исключения100101#### `exception asyncio.QueueEmpty`102103Это исключение возбуждается, когда метод [`get_nowait()`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.Queue.get_nowait) вызывается на пустой очереди.104105#### `exception asyncio.QueueFull`106107Исключение возбуждается, когда метод [`put_nowait()`](https://python-all.ru/3.8/library/asyncio-queue.html#asyncio.Queue.put_nowait) вызывается на очереди, достигшей своего *maxsize*.108109## Примеры110111Очереди можно использовать для распределения нагрузки между несколькими конкурентными задачами:112113```python114import asyncio115import random116import time117118async def worker(name, queue):119    while True:120        # Извлечь "рабочий элемент" из очереди.121        sleep_for = await queue.get()122123        # Подождать в течение "sleep_for" секунд.124        await asyncio.sleep(sleep_for)125126        # Уведомить очередь, что "рабочий элемент" обработан.127        queue.task_done()128129        print(f'{name} has slept for {sleep_for:.2f} seconds')130131async def main():132    # Создать очередь для хранения "рабочей нагрузки".133    queue = asyncio.Queue()134135    # Сгенерировать случайные задержки и поместить их в очередь.136    total_sleep_time = 0137    for _ in range(20):138        sleep_for = random.uniform(0.05, 1.0)139        total_sleep_time += sleep_for140        queue.put_nowait(sleep_for)141142    # Создать три рабочих задачи для параллельной обработки очереди.143    tasks = []144    for i in range(3):145        task = asyncio.create_task(worker(f'worker-{i}', queue))146        tasks.append(task)147148    # Ожидать полной обработки очереди.149    started_at = time.monotonic()150    await queue.join()151    total_slept_for = time.monotonic() - started_at152153    # Отменить наши рабочие задачи.154    for task in tasks:155        task.cancel()156    # Ожидать отмены всех рабочих задач.157    await asyncio.gather(*tasks, return_exceptions=True)158159    print('====')160    print(f'3 workers slept in parallel for {total_slept_for:.2f} seconds')161    print(f'total expected sleep time: {total_sleep_time:.2f} seconds')162163asyncio.run(main())164```165