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

asyncio-task.md

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

1> **Источник:** https://python-all.ru/3.5/library/asyncio-task.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 18.5.3. Задачи и корутины89## 18.5.3.1. Корутины1011Корутины, используемые с [`asyncio`](https://python-all.ru/3.5/library/asyncio.html#module-asyncio), могут быть реализованы с помощью выражения [`async def`](https://python-all.ru/3.5/reference/compound_stmts.html#async-def) или с использованием [генераторов](https://python-all.ru/3.5/glossary.html#term-generator). Тип корутин [`async def`](https://python-all.ru/3.5/reference/compound_stmts.html#async-def) был добавлен в Python 3.5 и рекомендуется, если нет необходимости поддерживать более старые версии Python.1213Корутины на основе генераторов следует декорировать с помощью [`@asyncio.coroutine`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.coroutine), хотя это строго не требуется. Декоратор обеспечивает совместимость с корутинами [`async def`](https://python-all.ru/3.5/reference/compound_stmts.html#async-def), а также служит документацией. Корутины на основе генераторов используют синтаксис `yield from`, введённый в [**PEP 380**](https://python-all.ru/3.5/library/asyncio-task.html), вместо исходного синтаксиса `yield`.1415Слово «корутина», как и слово «генератор», используется для двух различных (хотя и связанных) понятий:1617- Функция, которая определяет корутину (определение функции с помощью [`async def`](https://python-all.ru/3.5/reference/compound_stmts.html#async-def) или декорированная с помощью `@asyncio.coroutine`). Если требуется различение, мы будем называть её *корутинной функцией* ([`iscoroutinefunction()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.iscoroutinefunction) возвращает `True`).18- Объект, полученный вызовом корутинной функции. Этот объект представляет собой вычисление или операцию ввода-вывода (обычно их комбинацию), которая в конечном итоге завершится. Если требуется различение, мы будем называть его *объектом корутины* ([`iscoroutine()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.iscoroutine) возвращает `True`).1920Что может делать корутина:2122- `result = await future` или `result = yield from future` – приостанавливает корутину до завершения future, затем возвращает результат future или возбуждает исключение, которое будет распространено. (Если future отменено, будет возбуждено исключение `CancelledError`.) Обратите внимание, что задачи являются future, и всё сказанное о future применимо также к задачам.23- `result = await coroutine` или `result = yield from coroutine` – ожидание другой корутины для получения результата (или возбуждения исключения, которое будет распространено). Выражение `coroutine` должно быть *вызовом* другой корутины.24- `return expression` – выдать результат корутине, ожидающей данную через [`await`](https://python-all.ru/3.5/reference/expressions.html#await) или `yield from`.25- `raise exception` – возбудить исключение в корутине, которая ожидает данную через [`await`](https://python-all.ru/3.5/reference/expressions.html#await) или `yield from`.2627Вызов корутины не запускает выполнение её кода – объект корутины, возвращённый вызовом, ничего не делает, пока его выполнение не будет запланировано. Есть два основных способа запустить его: вызвать `await coroutine` или `yield from coroutine` из другой корутины (при условии, что другая корутина уже выполняется!) или запланировать его выполнение с помощью функции [`ensure_future()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.ensure_future) или метода [`AbstractEventLoop.create_task()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_task).2829Корутины (и задачи) могут выполняться только когда запущен цикл событий.3031#### `@asyncio.coroutine`3233Декоратор для пометки корутин на основе генераторов. Он позволяет генератору использовать `yield from` для вызова корутин [`async def`](https://python-all.ru/3.5/reference/compound_stmts.html#async-def), а также позволяет вызывать генератор из корутин [`async def`](https://python-all.ru/3.5/reference/compound_stmts.html#async-def), например, с помощью выражения [`await`](https://python-all.ru/3.5/reference/expressions.html#await).3435Нет необходимости декорировать сами корутины [`async def`](https://python-all.ru/3.5/reference/compound_stmts.html#async-def).3637Если из генератора не было выполнено yield from до его уничтожения, в журнал записывается сообщение об ошибке. См. [Обнаружение корутин, которые никогда не были запланированы](https://python-all.ru/3.5/library/asyncio-dev.html#asyncio-coroutine-not-scheduled).3839> **Примечание**40>41> В этой документации некоторые методы описаны как корутины, даже если они являются обычными функциями Python, возвращающими [`Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future). Это сделано намеренно, чтобы сохранить возможность изменять реализацию этих функций в будущем. Если такую функцию необходимо использовать в коде в стиле колбэков, оберните её результат с помощью [`ensure_future()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.ensure_future).4243### 18.5.3.1.1. Пример: корутина Hello World4445Пример корутины, выводящей `"Hello World"`:4647```python48import asyncio4950async def hello_world():51    print("Hello World!")5253loop = asyncio.get_event_loop()54# Блокирующий вызов, который возвращает управление после завершения корутины hello_world()55loop.run_until_complete(hello_world())56loop.close()57```5859> **См. также**60>61> Пример [Hello World с call\_soon()](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio-hello-world-callback) использует метод [`AbstractEventLoop.call_soon()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon) для планирования колбэка.6263### 18.5.3.1.2. Пример: корутина, показывающая текущую дату6465Пример корутины, отображающей текущую дату каждую секунду в течение 5 секунд, с помощью функции [`sleep()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.sleep):6667```python68import asyncio69import datetime7071async def display_date(loop):72    end_time = loop.time() + 5.073    while True:74        print(datetime.datetime.now())75        if (loop.time() + 1.0) >= end_time:76            break77        await asyncio.sleep(1)7879loop = asyncio.get_event_loop()80# Блокирующий вызов, который возвращает управление после завершения корутины display_date()81loop.run_until_complete(display_date(loop))82loop.close()83```8485> **См. также**86>87> Пример [отображение текущей даты с помощью call\_later()](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio-date-callback) использует колбэк с методом [`AbstractEventLoop.call_later()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_later).8889### 18.5.3.1.3. Пример: цепочка корутин9091Пример соединения корутин в цепочку:9293```python94import asyncio9596async def compute(x, y):97    print("Compute %s + %s ..." % (x, y))98    await asyncio.sleep(1.0)99    return x + y100101async def print_sum(x, y):102    result = await compute(x, y)103    print("%s + %s = %s" % (x, y, result))104105loop = asyncio.get_event_loop()106loop.run_until_complete(print_sum(1, 2))107loop.close()108```109110`compute()` зацеплена за `print_sum()`: корутина `print_sum()` ожидает завершения `compute()`, прежде чем вернуть свой результат.111112Диаграмма последовательности примера:113114![../_images/tulip_coro.png](https://python-all.ru/3.5/_images/tulip_coro.png)115116«Задача» создаётся методом [`AbstractEventLoop.run_until_complete()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_until_complete), когда он получает объект корутины вместо задачи.117118Диаграмма показывает поток управления, она не описывает точно, как всё работает внутри. Например, корутина sleep создаёт внутренний future, который использует [`AbstractEventLoop.call_later()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_later), чтобы разбудить задачу через 1 секунду.119120## 18.5.3.2. InvalidStateError121122#### `exception asyncio.InvalidStateError`123124Операция не разрешена в этом состоянии.125126## 18.5.3.3. TimeoutError127128#### `exception asyncio.TimeoutError`129130Операция превысила заданный срок.131132> **Примечание**133>134> Это исключение отличается от встроенного исключения [`TimeoutError`](https://python-all.ru/3.5/library/exceptions.html#TimeoutError)!135136## 18.5.3.4. Future137138#### `class asyncio.Future(*, loop=None)`139140Этот класс *почти* совместим с [`concurrent.futures.Future`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.Future).141142Отличия:143144- [`result()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future.result) и [`exception()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future.exception) не принимают аргумент таймаута и вызывают исключение, если future ещё не завершён.145- Колбэки, зарегистрированные с помощью [`add_done_callback()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future.add_done_callback), всегда вызываются через [`call_soon_threadsafe()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon_threadsafe) цикла событий.146- Этот класс несовместим с функциями [`wait()`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.wait) и [`as_completed()`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.as_completed) из пакета [`concurrent.futures`](https://python-all.ru/3.5/library/concurrent.futures.html#module-concurrent.futures).147148This class is [не является потокобезопасным](https://python-all.ru/3.5/library/asyncio-dev.html#asyncio-multithreading).149150#### `cancel()`151152Отменить future и запланировать вызов колбэков.153154Если future уже завершён или отменён, вернуть `False`. В противном случае изменить состояние future на «отменён», запланировать вызов колбэков и вернуть `True`.155156#### `cancelled()`157158Вернуть `True`, если future был отменён.159160#### `done()`161162Вернуть `True`, если future завершён.163164«Завершён» означает либо наличие результата или исключения, либо то, что future был отменён.165166#### `result()`167168Вернуть результат, который представляет этот future.169170Если future был отменён, возбуждается `CancelledError`. Если результат future ещё недоступен, возбуждается [`InvalidStateError`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.InvalidStateError). Если future завершён и для него установлено исключение, возбуждается это исключение.171172#### `exception()`173174Вернуть исключение, которое было установлено для этого future.175176Исключение (или `None`, если исключение не было установлено) возвращается только если future завершён. Если future был отменён, возбуждается `CancelledError`. Если future ещё не завершён, возбуждается [`InvalidStateError`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.InvalidStateError).177178#### `add_done_callback(fn)`179180Добавить колбэк, который будет вызван, когда future станет завершённым.181182Колбэк вызывается с одним аргументом – объектом future. Если future уже завершён на момент вызова, колбэк планируется с помощью [`call_soon()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon).183184[Используйте functools.partial для передачи параметров колбэку](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio-pass-keywords). Например, `fut.add_done_callback(functools.partial(print, "Future:", flush=True))` вызовет `print("Future:", fut, flush=True)`.185186#### `remove_done_callback(fn)`187188Удалить все экземпляры колбэка из списка «вызвать при завершении».189190Возвращает количество удалённых колбэков.191192#### `set_result(result)`193194Пометить future как завершённый и установить его результат.195196Если метод вызывается, когда future уже завершён, возбуждается [`InvalidStateError`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.InvalidStateError).197198#### `set_exception(exception)`199200Пометить future как завершённый и установить исключение.201202Если метод вызывается, когда future уже завершён, возбуждается [`InvalidStateError`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.InvalidStateError).203204### 18.5.3.4.1. Пример: Future с run\_until\_complete()205206Пример сочетания [`Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future) и [корутинной функции](https://python-all.ru/3.5/library/asyncio-task.html#coroutine):207208```python209import asyncio210211async def slow_operation(future):212    await asyncio.sleep(1)213    future.set_result('Future is done!')214215loop = asyncio.get_event_loop()216future = asyncio.Future()217asyncio.ensure_future(slow_operation(future))218loop.run_until_complete(future)219print(future.result())220loop.close()221```222223Корутинная функция отвечает за вычисление (занимает 1 секунду) и сохраняет результат в future. Метод [`run_until_complete()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_until_complete) ожидает завершения future.224225> **Примечание**226>227> Метод [`run_until_complete()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_until_complete) внутри использует метод [`add_done_callback()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future.add_done_callback), чтобы получать уведомление о том, что future завершена.228229### 18.5.3.4.2. Пример: Future с run\_forever()230231Предыдущий пример можно записать иначе, используя метод [`Future.add_done_callback()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future.add_done_callback), чтобы явно описать поток управления:232233```python234import asyncio235236async def slow_operation(future):237    await asyncio.sleep(1)238    future.set_result('Future is done!')239240def got_result(future):241    print(future.result())242    loop.stop()243244loop = asyncio.get_event_loop()245future = asyncio.Future()246asyncio.ensure_future(slow_operation(future))247future.add_done_callback(got_result)248try:249    loop.run_forever()250finally:251    loop.close()252```253254В этом примере future используется для связывания `slow_operation()` с `got_result()`: когда `slow_operation()` завершается, вызывается `got_result()` с результатом.255256## 18.5.3.5. Задача257258#### `class asyncio.Task(coro, *, loop=None)`259260Планирует выполнение [корутины](https://python-all.ru/3.5/library/asyncio-task.html#coroutine): оборачивает её в future. Задача является подклассом [`Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future).261262Задача отвечает за выполнение корутины в цикле событий. Если обёрнутая корутина использует yield from для future, задача приостанавливает выполнение обёрнутой корутины и ожидает завершения future. Когда future завершается, выполнение обёрнутой корутины возобновляется с результатом или исключением future.263264Циклы событий используют кооперативное планирование: цикл событий запускает только одну задачу за раз. Другие задачи могут выполняться параллельно, если другие циклы событий работают в разных потоках. Пока задача ожидает завершения future, цикл событий выполняет новую задачу.265266Отмена задачи отличается от отмены future. Вызов [`cancel()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Task.cancel) вызовет [`CancelledError`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.CancelledError) в обёрнутую корутину. [`cancelled()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future.cancelled) возвращает `True`, только если обёрнутая корутина не перехватила исключение [`CancelledError`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.CancelledError) или вызвала исключение [`CancelledError`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.CancelledError).267268Если ожидающая задача уничтожается, выполнение её обёрнутой [корутины](https://python-all.ru/3.5/library/asyncio-task.html#coroutine) не завершилось. Вероятно, это ошибка, и в журнал записывается предупреждение: см. [Ожидающая задача уничтожена](https://python-all.ru/3.5/library/asyncio-dev.html#asyncio-pending-task-destroyed).269270Не создавайте экземпляры [`Task`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Task) напрямую: используйте функцию [`ensure_future()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.ensure_future) или метод [`AbstractEventLoop.create_task()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_task).271272This class is [не является потокобезопасным](https://python-all.ru/3.5/library/asyncio-dev.html#asyncio-multithreading).273274#### `classmethod all_tasks(loop=None)`275276Возвращает набор всех задач для цикла событий.277278По умолчанию возвращаются все задачи для текущего цикла событий.279280#### `classmethod current_task(loop=None)`281282Возвращает текущую выполняющуюся задачу в цикле событий или `None`.283284По умолчанию возвращается текущая задача для текущего цикла событий.285286`None` возвращается при вызове не в контексте [`Task`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Task).287288#### `cancel()`289290Запрашивает отмену этой задачи.291292Это организует вызов [`CancelledError`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.CancelledError) в обёрнутую корутину на следующем цикле событий. Корутина затем может очистить ресурсы или даже отклонить запрос с помощью try/except/finally.293294В отличие от [`Future.cancel()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future.cancel), это не гарантирует, что задача будет отменена: исключение может быть перехвачено и обработано, что отложит отмену задачи или предотвратит её полностью. Задача также может вернуть значение или вызвать другое исключение.295296Сразу после вызова этого метода [`cancelled()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future.cancelled) не вернёт `True` (если задача уже не была отменена). Задача будет отмечена как отменённая, когда обёрнутая корутина завершится с исключением [`CancelledError`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.CancelledError) (даже если [`cancel()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Task.cancel) не вызывался).297298#### `get_stack(*, limit=None)`299300Возвращает список фреймов стека для корутины этой задачи.301302Если корутина не завершена, возвращается стек, в котором она приостановлена. Если корутина успешно завершилась или была отменена, возвращается пустой список. Если корутина была прервана исключением, возвращается список фреймов traceback.303304Кадры всегда упорядочены от старых к новым.305306Необязательный параметр limit задаёт максимальное количество возвращаемых фреймов; по умолчанию возвращаются все доступные фреймы. Его значение различается в зависимости от того, возвращается стек или traceback: возвращаются самые новые фреймы стека, но самые старые фреймы traceback. (Это соответствует поведению модуля traceback.)307308По независящим от нас причинам для приостановленной корутины возвращается только один фрейм стека.309310#### `print_stack(*, limit=None, file=None)`311312Выводит стек или traceback для корутины этой задачи.313314Вывод похож на вывод модуля traceback для фреймов, полученных с помощью get\_stack(). Аргумент limit передаётся в get\_stack(). Аргумент file – это I/O поток, в который записывается вывод; по умолчанию вывод записывается в sys.stderr.315316### 18.5.3.5.1. Пример: параллельное выполнение задач317318Пример параллельного выполнения 3 задач (A, B, C):319320```python321import asyncio322323async def factorial(name, number):324    f = 1325    for i in range(2, number+1):326        print("Task %s: Compute factorial(%s)..." % (name, i))327        await asyncio.sleep(1)328        f *= i329    print("Task %s: factorial(%s) = %s" % (name, number, f))330331loop = asyncio.get_event_loop()332loop.run_until_complete(asyncio.gather(333    factorial("A", 2),334    factorial("B", 3),335    factorial("C", 4),336))337loop.close()338```339340Вывод:341342```python343Task A: Compute factorial(2)...344Task B: Compute factorial(2)...345Task C: Compute factorial(2)...346Task A: factorial(2) = 2347Task B: Compute factorial(3)...348Task C: Compute factorial(3)...349Task B: factorial(3) = 6350Task C: Compute factorial(4)...351Task C: factorial(4) = 24352```353354Задача автоматически планируется на выполнение при её создании. Цикл событий останавливается, когда все задачи завершены.355356## 18.5.3.6. Функции задач357358> **Примечание**359>360> В приведённых ниже функциях опциональный аргумент *loop* позволяет явно задать объект цикла событий, используемый нижележащей задачей или корутиной. Если он не указан, используется цикл событий по умолчанию.361362#### `asyncio.as_completed(fs, *, loop=None, timeout=None)`363364Возвращает итератор, значения которого при ожидании являются экземплярами [`Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future).365366Вызывает [`asyncio.TimeoutError`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.TimeoutError), если время ожидания истекло до завершения всех Future.367368Пример:369370```python371for f in as_completed(fs):372    result = yield from f  # Выражение 'yield from' может возбуждать исключение373    # Используйте результат374```375376> **Примечание**377>378> Будущие объекты `f` не обязательно являются элементами fs.379380#### `asyncio.ensure_future(coro_or_future, *, loop=None)`381382Планирует выполнение [корутинного объекта](https://python-all.ru/3.5/library/asyncio-task.html#coroutine): оборачивает его в future. Возвращает объект [`Task`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Task).383384Если аргумент является [`Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future), он возвращается напрямую.385386Новое в версии 3.4.4.387388Изменено в версии 3.5.1: Функция принимает любой [ожидаемый](https://python-all.ru/3.5/glossary.html#term-awaitable) объект.389390> **См. также**391>392> Метод [`AbstractEventLoop.create_task()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_task).393394#### `asyncio.async(coro_or_future, *, loop=None)`395396Устаревший псевдоним [`ensure_future()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.ensure_future).397398Устарело с версии 3.4.4.399400#### `asyncio.wrap_future(future, *, loop=None)`401402Оборачивает объект [`concurrent.futures.Future`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.Future) в объект [`Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future).403404#### `asyncio.gather(*coros_or_futures, loop=None, return_exceptions=False)`405406Возвращает future, агрегирующий результаты от заданных корутинных объектов или future.407408Все future должны использовать один и тот же цикл событий. Если все задачи выполнены успешно, результатом возвращённого future будет список результатов (в порядке исходной последовательности, не обязательно в порядке поступления результатов). Если *return\_exceptions* равен true, исключения в задачах обрабатываются так же, как успешные результаты, и собираются в результирующий список; в противном случае первое возникшее исключение немедленно распространяется на возвращённый future.409410Отмена: если внешний Future отменён, все дочерние (ещё не завершённые) также отменяются. Если какой-либо дочерний элемент отменён, это рассматривается так, как если бы он вызвал [`CancelledError`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.CancelledError) – в этом случае внешний Future *не* отменяется. (Это предотвращает отмену одного дочернего элемента, которая может привести к отмене других.)411412#### `asyncio.iscoroutine(obj)`413414Возвращает `True`, если *obj* является [корутинным объектом](https://python-all.ru/3.5/library/asyncio-task.html#coroutine), который может быть основан на генераторе или корутине [`async def`](https://python-all.ru/3.5/reference/compound_stmts.html#async-def).415416#### `asyncio.iscoroutinefunction(func)`417418Возвращает `True`, если *func* определена как [корутинная функция](https://python-all.ru/3.5/library/asyncio-task.html#coroutine), которая может быть декорированной функцией-генератором или функцией [`async def`](https://python-all.ru/3.5/reference/compound_stmts.html#async-def).419420#### `asyncio.run_coroutine_threadsafe(coro, loop)`421422Отправляет [корутинный объект](https://python-all.ru/3.5/library/asyncio-task.html#coroutine) в заданный цикл событий.423424Возвращает [`concurrent.futures.Future`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.Future) для доступа к результату.425426Эта функция предназначена для вызова из другого потока, отличного от того, в котором работает цикл событий. Использование:427428```python429# Создать корутину430coro = asyncio.sleep(1, result=3)431# Отправить корутину в заданный цикл432future = asyncio.run_coroutine_threadsafe(coro, loop)433# Ожидать результат с необязательным аргументом таймаута434assert future.result(timeout) == 3435```436437Если в корутине возникнет исключение, возвращённый future будет уведомлён. Его также можно использовать для отмены задачи в цикле событий:438439```python440try:441    result = future.result(timeout)442except asyncio.TimeoutError:443    print('The coroutine took too long, cancelling the task...')444    future.cancel()445except Exception as exc:446    print('The coroutine raised an exception: {!r}'.format(exc))447else:448    print('The coroutine returned: {!r}'.format(result))449```450451См. раздел [concurrency and multithreading](https://python-all.ru/3.5/library/asyncio-dev.html#asyncio-multithreading) документации.452453> **Примечание**454>455> В отличие от других функций модуля, [`run_coroutine_threadsafe()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.run_coroutine_threadsafe) требует явной передачи аргумента *loop*.456457Новое в версии 3.5.1.458459#### `coroutine asyncio.sleep(delay, result=None, *, loop=None)`460461Создаёт [корутину](https://python-all.ru/3.5/library/asyncio-task.html#coroutine), которая завершается через указанное время (в секундах). Если указан *result*, то при завершении корутины он передаётся вызывающему коду.462463Точность задержки зависит от [гранулярности цикла событий](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio-delayed-calls).464465Эта функция – [корутина](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).466467#### `asyncio.shield(arg, *, loop=None)`468469Ожидает future, защищая его от отмены.470471Выражение:472473```python474res = yield from shield(something())475```476477полностью эквивалентна следующему выражению:478479```python480res = yield from something()481```482483*except* that if the coroutine containing it is cancelled, the task running in `something()` is not cancelled. From the point of view of `something()`, the cancellation did not happen. But its caller is still cancelled, so the yield-from expression still raises [`CancelledError`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.CancelledError). Note: If `something()` is cancelled by other means this will still cancel `shield()`.484485Если требуется полностью игнорировать отмену (не рекомендуется), можно объединить `shield()` с конструкцией try/except следующим образом:486487```python488try:489    res = yield from shield(something())490except CancelledError:491    res = None492```493494#### `coroutine asyncio.wait(futures, *, loop=None, timeout=None, return_when=ALL_COMPLETED)`495496Ожидает завершения объектов Future и корутин, заданных последовательностью *futures*. Корутины будут обёрнуты в задачи. Возвращает два набора [`Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future): (done, pending).497498Последовательность *futures* не должна быть пустой.499500*timeout* можно использовать для управления максимальным количеством секунд ожидания перед возвратом. *timeout* может быть целым числом или числом с плавающей запятой. Если *timeout* не указан или `None`, время ожидания не ограничено.501502*return\_when* указывает, когда функция должна вернуть результат. Значением должна быть одна из следующих констант модуля [`concurrent.futures`](https://python-all.ru/3.5/library/concurrent.futures.html#module-concurrent.futures):503504| Константа | Описание |505| --- | --- |506| `FIRST_COMPLETED` | Функция вернёт результат, когда любой future завершится или будет отменён. |507| `FIRST_EXCEPTION` | Функция вернёт результат, когда любой future завершится, возбудив исключение. Если ни один future не возбудит исключение, это эквивалентно `ALL_COMPLETED`. |508| `ALL_COMPLETED` | Функция вернёт результат, когда все future завершатся или будут отменены. |509510Эта функция – [корутина](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).511512Использование:513514```python515done, pending = yield from asyncio.wait(fs)516```517518> **Примечание**519>520> Это не возбуждает [`asyncio.TimeoutError`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.TimeoutError)! Future, которые не завершены при наступлении тайм-аута, возвращаются во втором наборе.521522#### `coroutine asyncio.wait_for(fut, timeout, *, loop=None)`523524Ожидает завершения единственного [`Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future) или [объекта-корутины](https://python-all.ru/3.5/library/asyncio-task.html#coroutine) с тайм-аутом. Если *timeout* равно `None`, блокируется до завершения future.525526Корутина будет обёрнута в [`Task`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Task).527528Возвращает результат Future или корутины. При наступлении тайм-аута она отменяет задачу и возбуждает [`asyncio.TimeoutError`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.TimeoutError). Чтобы избежать отмены задачи, оберните её в [`shield()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.shield).529530Если ожидание отменяется, future *fut* также отменяется.531532Эта функция является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine), пример использования:533534```python535result = yield from asyncio.wait_for(fut, 60.0)536```537538Изменено в версии 3.4.3: Если ожидание отменяется, future *fut* теперь также отменяется.539