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

---

# 18.5.3. Задачи и корутины

## 18.5.3.1. Корутины

Корутины, используемые с [`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.

Корутины на основе генераторов следует декорировать с помощью [`@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`.

Слово «корутина», как и слово «генератор», используется для двух различных (хотя и связанных) понятий:

- Функция, которая определяет корутину (определение функции с помощью [`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`).
- Объект, полученный вызовом корутинной функции. Этот объект представляет собой вычисление или операцию ввода-вывода (обычно их комбинацию), которая в конечном итоге завершится. Если требуется различение, мы будем называть его *объектом корутины* ([`iscoroutine()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.iscoroutine) возвращает `True`).

Что может делать корутина:

- `result = await future` или `result = yield from future` – приостанавливает корутину до завершения future, затем возвращает результат future или возбуждает исключение, которое будет распространено. (Если future отменено, будет возбуждено исключение `CancelledError`.) Обратите внимание, что задачи являются future, и всё сказанное о future применимо также к задачам.
- `result = await coroutine` или `result = yield from coroutine` – ожидание другой корутины для получения результата (или возбуждения исключения, которое будет распространено). Выражение `coroutine` должно быть *вызовом* другой корутины.
- `return expression` – выдать результат корутине, ожидающей данную через [`await`](https://python-all.ru/3.5/reference/expressions.html#await) или `yield from`.
- `raise exception` – возбудить исключение в корутине, которая ожидает данную через [`await`](https://python-all.ru/3.5/reference/expressions.html#await) или `yield from`.

Вызов корутины не запускает выполнение её кода – объект корутины, возвращённый вызовом, ничего не делает, пока его выполнение не будет запланировано. Есть два основных способа запустить его: вызвать `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).

Корутины (и задачи) могут выполняться только когда запущен цикл событий.

#### `@asyncio.coroutine`

Декоратор для пометки корутин на основе генераторов. Он позволяет генератору использовать `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).

Нет необходимости декорировать сами корутины [`async def`](https://python-all.ru/3.5/reference/compound_stmts.html#async-def).

Если из генератора не было выполнено yield from до его уничтожения, в журнал записывается сообщение об ошибке. См. [Обнаружение корутин, которые никогда не были запланированы](https://python-all.ru/3.5/library/asyncio-dev.html#asyncio-coroutine-not-scheduled).

> **Примечание**
>
> В этой документации некоторые методы описаны как корутины, даже если они являются обычными функциями 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).

### 18.5.3.1.1. Пример: корутина Hello World

Пример корутины, выводящей `"Hello World"`:

```python
import asyncio

async def hello_world():
    print("Hello World!")

loop = asyncio.get_event_loop()
# Блокирующий вызов, который возвращает управление после завершения корутины hello_world()
loop.run_until_complete(hello_world())
loop.close()
```

> **См. также**
>
> Пример [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) для планирования колбэка.

### 18.5.3.1.2. Пример: корутина, показывающая текущую дату

Пример корутины, отображающей текущую дату каждую секунду в течение 5 секунд, с помощью функции [`sleep()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.sleep):

```python
import asyncio
import datetime

async def display_date(loop):
    end_time = loop.time() + 5.0
    while True:
        print(datetime.datetime.now())
        if (loop.time() + 1.0) >= end_time:
            break
        await asyncio.sleep(1)

loop = asyncio.get_event_loop()
# Блокирующий вызов, который возвращает управление после завершения корутины display_date()
loop.run_until_complete(display_date(loop))
loop.close()
```

> **См. также**
>
> Пример [отображение текущей даты с помощью 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).

### 18.5.3.1.3. Пример: цепочка корутин

Пример соединения корутин в цепочку:

```python
import asyncio

async def compute(x, y):
    print("Compute %s + %s ..." % (x, y))
    await asyncio.sleep(1.0)
    return x + y

async def print_sum(x, y):
    result = await compute(x, y)
    print("%s + %s = %s" % (x, y, result))

loop = asyncio.get_event_loop()
loop.run_until_complete(print_sum(1, 2))
loop.close()
```

`compute()` зацеплена за `print_sum()`: корутина `print_sum()` ожидает завершения `compute()`, прежде чем вернуть свой результат.

Диаграмма последовательности примера:

![../_images/tulip_coro.png](https://python-all.ru/3.5/_images/tulip_coro.png)

«Задача» создаётся методом [`AbstractEventLoop.run_until_complete()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_until_complete), когда он получает объект корутины вместо задачи.

Диаграмма показывает поток управления, она не описывает точно, как всё работает внутри. Например, корутина sleep создаёт внутренний future, который использует [`AbstractEventLoop.call_later()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_later), чтобы разбудить задачу через 1 секунду.

## 18.5.3.2. InvalidStateError

#### `exception asyncio.InvalidStateError`

Операция не разрешена в этом состоянии.

## 18.5.3.3. TimeoutError

#### `exception asyncio.TimeoutError`

Операция превысила заданный срок.

> **Примечание**
>
> Это исключение отличается от встроенного исключения [`TimeoutError`](https://python-all.ru/3.5/library/exceptions.html#TimeoutError)!

## 18.5.3.4. Future

#### `class asyncio.Future(*, loop=None)`

Этот класс *почти* совместим с [`concurrent.futures.Future`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.Future).

Отличия:

- [`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 ещё не завершён.
- Колбэки, зарегистрированные с помощью [`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) цикла событий.
- Этот класс несовместим с функциями [`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).

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

#### `cancel()`

Отменить future и запланировать вызов колбэков.

Если future уже завершён или отменён, вернуть `False`. В противном случае изменить состояние future на «отменён», запланировать вызов колбэков и вернуть `True`.

#### `cancelled()`

Вернуть `True`, если future был отменён.

#### `done()`

Вернуть `True`, если future завершён.

«Завершён» означает либо наличие результата или исключения, либо то, что future был отменён.

#### `result()`

Вернуть результат, который представляет этот future.

Если future был отменён, возбуждается `CancelledError`. Если результат future ещё недоступен, возбуждается [`InvalidStateError`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.InvalidStateError). Если future завершён и для него установлено исключение, возбуждается это исключение.

#### `exception()`

Вернуть исключение, которое было установлено для этого future.

Исключение (или `None`, если исключение не было установлено) возвращается только если future завершён. Если future был отменён, возбуждается `CancelledError`. Если future ещё не завершён, возбуждается [`InvalidStateError`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.InvalidStateError).

#### `add_done_callback(fn)`

Добавить колбэк, который будет вызван, когда future станет завершённым.

Колбэк вызывается с одним аргументом – объектом future. Если future уже завершён на момент вызова, колбэк планируется с помощью [`call_soon()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon).

[Используйте 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)`.

#### `remove_done_callback(fn)`

Удалить все экземпляры колбэка из списка «вызвать при завершении».

Возвращает количество удалённых колбэков.

#### `set_result(result)`

Пометить future как завершённый и установить его результат.

Если метод вызывается, когда future уже завершён, возбуждается [`InvalidStateError`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.InvalidStateError).

#### `set_exception(exception)`

Пометить future как завершённый и установить исключение.

Если метод вызывается, когда future уже завершён, возбуждается [`InvalidStateError`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.InvalidStateError).

### 18.5.3.4.1. Пример: Future с run\_until\_complete()

Пример сочетания [`Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future) и [корутинной функции](https://python-all.ru/3.5/library/asyncio-task.html#coroutine):

```python
import asyncio

async def slow_operation(future):
    await asyncio.sleep(1)
    future.set_result('Future is done!')

loop = asyncio.get_event_loop()
future = asyncio.Future()
asyncio.ensure_future(slow_operation(future))
loop.run_until_complete(future)
print(future.result())
loop.close()
```

Корутинная функция отвечает за вычисление (занимает 1 секунду) и сохраняет результат в future. Метод [`run_until_complete()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_until_complete) ожидает завершения future.

> **Примечание**
>
> Метод [`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 завершена.

### 18.5.3.4.2. Пример: Future с run\_forever()

Предыдущий пример можно записать иначе, используя метод [`Future.add_done_callback()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future.add_done_callback), чтобы явно описать поток управления:

```python
import asyncio

async def slow_operation(future):
    await asyncio.sleep(1)
    future.set_result('Future is done!')

def got_result(future):
    print(future.result())
    loop.stop()

loop = asyncio.get_event_loop()
future = asyncio.Future()
asyncio.ensure_future(slow_operation(future))
future.add_done_callback(got_result)
try:
    loop.run_forever()
finally:
    loop.close()
```

В этом примере future используется для связывания `slow_operation()` с `got_result()`: когда `slow_operation()` завершается, вызывается `got_result()` с результатом.

## 18.5.3.5. Задача

#### `class asyncio.Task(coro, *, loop=None)`

Планирует выполнение [корутины](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).

Задача отвечает за выполнение корутины в цикле событий. Если обёрнутая корутина использует yield from для future, задача приостанавливает выполнение обёрнутой корутины и ожидает завершения future. Когда future завершается, выполнение обёрнутой корутины возобновляется с результатом или исключением future.

Циклы событий используют кооперативное планирование: цикл событий запускает только одну задачу за раз. Другие задачи могут выполняться параллельно, если другие циклы событий работают в разных потоках. Пока задача ожидает завершения future, цикл событий выполняет новую задачу.

Отмена задачи отличается от отмены 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).

Если ожидающая задача уничтожается, выполнение её обёрнутой [корутины](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).

Не создавайте экземпляры [`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).

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

#### `classmethod all_tasks(loop=None)`

Возвращает набор всех задач для цикла событий.

По умолчанию возвращаются все задачи для текущего цикла событий.

#### `classmethod current_task(loop=None)`

Возвращает текущую выполняющуюся задачу в цикле событий или `None`.

По умолчанию возвращается текущая задача для текущего цикла событий.

`None` возвращается при вызове не в контексте [`Task`](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) в обёрнутую корутину на следующем цикле событий. Корутина затем может очистить ресурсы или даже отклонить запрос с помощью try/except/finally.

В отличие от [`Future.cancel()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future.cancel), это не гарантирует, что задача будет отменена: исключение может быть перехвачено и обработано, что отложит отмену задачи или предотвратит её полностью. Задача также может вернуть значение или вызвать другое исключение.

Сразу после вызова этого метода [`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) не вызывался).

#### `get_stack(*, limit=None)`

Возвращает список фреймов стека для корутины этой задачи.

Если корутина не завершена, возвращается стек, в котором она приостановлена. Если корутина успешно завершилась или была отменена, возвращается пустой список. Если корутина была прервана исключением, возвращается список фреймов traceback.

Кадры всегда упорядочены от старых к новым.

Необязательный параметр limit задаёт максимальное количество возвращаемых фреймов; по умолчанию возвращаются все доступные фреймы. Его значение различается в зависимости от того, возвращается стек или traceback: возвращаются самые новые фреймы стека, но самые старые фреймы traceback. (Это соответствует поведению модуля traceback.)

По независящим от нас причинам для приостановленной корутины возвращается только один фрейм стека.

#### `print_stack(*, limit=None, file=None)`

Выводит стек или traceback для корутины этой задачи.

Вывод похож на вывод модуля traceback для фреймов, полученных с помощью get\_stack(). Аргумент limit передаётся в get\_stack(). Аргумент file – это I/O поток, в который записывается вывод; по умолчанию вывод записывается в sys.stderr.

### 18.5.3.5.1. Пример: параллельное выполнение задач

Пример параллельного выполнения 3 задач (A, B, C):

```python
import asyncio

async def factorial(name, number):
    f = 1
    for i in range(2, number+1):
        print("Task %s: Compute factorial(%s)..." % (name, i))
        await asyncio.sleep(1)
        f *= i
    print("Task %s: factorial(%s) = %s" % (name, number, f))

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(
    factorial("A", 2),
    factorial("B", 3),
    factorial("C", 4),
))
loop.close()
```

Вывод:

```python
Task A: Compute factorial(2)...
Task B: Compute factorial(2)...
Task C: Compute factorial(2)...
Task A: factorial(2) = 2
Task B: Compute factorial(3)...
Task C: Compute factorial(3)...
Task B: factorial(3) = 6
Task C: Compute factorial(4)...
Task C: factorial(4) = 24
```

Задача автоматически планируется на выполнение при её создании. Цикл событий останавливается, когда все задачи завершены.

## 18.5.3.6. Функции задач

> **Примечание**
>
> В приведённых ниже функциях опциональный аргумент *loop* позволяет явно задать объект цикла событий, используемый нижележащей задачей или корутиной. Если он не указан, используется цикл событий по умолчанию.

#### `asyncio.as_completed(fs, *, loop=None, timeout=None)`

Возвращает итератор, значения которого при ожидании являются экземплярами [`Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future).

Вызывает [`asyncio.TimeoutError`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.TimeoutError), если время ожидания истекло до завершения всех Future.

Пример:

```python
for f in as_completed(fs):
    result = yield from f  # Выражение 'yield from' может возбуждать исключение
    # Используйте результат
```

> **Примечание**
>
> Будущие объекты `f` не обязательно являются элементами fs.

#### `asyncio.ensure_future(coro_or_future, *, loop=None)`

Планирует выполнение [корутинного объекта](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).

Если аргумент является [`Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future), он возвращается напрямую.

Новое в версии 3.4.4.

Изменено в версии 3.5.1: Функция принимает любой [ожидаемый](https://python-all.ru/3.5/glossary.html#term-awaitable) объект.

> **См. также**
>
> Метод [`AbstractEventLoop.create_task()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_task).

#### `asyncio.async(coro_or_future, *, loop=None)`

Устаревший псевдоним [`ensure_future()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.ensure_future).

Устарело с версии 3.4.4.

#### `asyncio.wrap_future(future, *, loop=None)`

Оборачивает объект [`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).

#### `asyncio.gather(*coros_or_futures, loop=None, return_exceptions=False)`

Возвращает future, агрегирующий результаты от заданных корутинных объектов или future.

Все future должны использовать один и тот же цикл событий. Если все задачи выполнены успешно, результатом возвращённого future будет список результатов (в порядке исходной последовательности, не обязательно в порядке поступления результатов). Если *return\_exceptions* равен true, исключения в задачах обрабатываются так же, как успешные результаты, и собираются в результирующий список; в противном случае первое возникшее исключение немедленно распространяется на возвращённый future.

Отмена: если внешний Future отменён, все дочерние (ещё не завершённые) также отменяются. Если какой-либо дочерний элемент отменён, это рассматривается так, как если бы он вызвал [`CancelledError`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.CancelledError) – в этом случае внешний Future *не* отменяется. (Это предотвращает отмену одного дочернего элемента, которая может привести к отмене других.)

#### `asyncio.iscoroutine(obj)`

Возвращает `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).

#### `asyncio.iscoroutinefunction(func)`

Возвращает `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).

#### `asyncio.run_coroutine_threadsafe(coro, loop)`

Отправляет [корутинный объект](https://python-all.ru/3.5/library/asyncio-task.html#coroutine) в заданный цикл событий.

Возвращает [`concurrent.futures.Future`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.Future) для доступа к результату.

Эта функция предназначена для вызова из другого потока, отличного от того, в котором работает цикл событий. Использование:

```python
# Создать корутину
coro = asyncio.sleep(1, result=3)
# Отправить корутину в заданный цикл
future = asyncio.run_coroutine_threadsafe(coro, loop)
# Ожидать результат с необязательным аргументом таймаута
assert future.result(timeout) == 3
```

Если в корутине возникнет исключение, возвращённый future будет уведомлён. Его также можно использовать для отмены задачи в цикле событий:

```python
try:
    result = future.result(timeout)
except asyncio.TimeoutError:
    print('The coroutine took too long, cancelling the task...')
    future.cancel()
except Exception as exc:
    print('The coroutine raised an exception: {!r}'.format(exc))
else:
    print('The coroutine returned: {!r}'.format(result))
```

См. раздел [concurrency and multithreading](https://python-all.ru/3.5/library/asyncio-dev.html#asyncio-multithreading) документации.

> **Примечание**
>
> В отличие от других функций модуля, [`run_coroutine_threadsafe()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.run_coroutine_threadsafe) требует явной передачи аргумента *loop*.

Новое в версии 3.5.1.

#### `coroutine asyncio.sleep(delay, result=None, *, loop=None)`

Создаёт [корутину](https://python-all.ru/3.5/library/asyncio-task.html#coroutine), которая завершается через указанное время (в секундах). Если указан *result*, то при завершении корутины он передаётся вызывающему коду.

Точность задержки зависит от [гранулярности цикла событий](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio-delayed-calls).

Эта функция – [корутина](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).

#### `asyncio.shield(arg, *, loop=None)`

Ожидает future, защищая его от отмены.

Выражение:

```python
res = yield from shield(something())
```

полностью эквивалентна следующему выражению:

```python
res = yield from something()
```

*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()`.

Если требуется полностью игнорировать отмену (не рекомендуется), можно объединить `shield()` с конструкцией try/except следующим образом:

```python
try:
    res = yield from shield(something())
except CancelledError:
    res = None
```

#### `coroutine asyncio.wait(futures, *, loop=None, timeout=None, return_when=ALL_COMPLETED)`

Ожидает завершения объектов Future и корутин, заданных последовательностью *futures*. Корутины будут обёрнуты в задачи. Возвращает два набора [`Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future): (done, pending).

Последовательность *futures* не должна быть пустой.

*timeout* можно использовать для управления максимальным количеством секунд ожидания перед возвратом. *timeout* может быть целым числом или числом с плавающей запятой. Если *timeout* не указан или `None`, время ожидания не ограничено.

*return\_when* указывает, когда функция должна вернуть результат. Значением должна быть одна из следующих констант модуля [`concurrent.futures`](https://python-all.ru/3.5/library/concurrent.futures.html#module-concurrent.futures):

| Константа | Описание |
| --- | --- |
| `FIRST_COMPLETED` | Функция вернёт результат, когда любой future завершится или будет отменён. |
| `FIRST_EXCEPTION` | Функция вернёт результат, когда любой future завершится, возбудив исключение. Если ни один future не возбудит исключение, это эквивалентно `ALL_COMPLETED`. |
| `ALL_COMPLETED` | Функция вернёт результат, когда все future завершатся или будут отменены. |

Эта функция – [корутина](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).

Использование:

```python
done, pending = yield from asyncio.wait(fs)
```

> **Примечание**
>
> Это не возбуждает [`asyncio.TimeoutError`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.TimeoutError)! Future, которые не завершены при наступлении тайм-аута, возвращаются во втором наборе.

#### `coroutine asyncio.wait_for(fut, timeout, *, loop=None)`

Ожидает завершения единственного [`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.

Корутина будет обёрнута в [`Task`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Task).

Возвращает результат 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).

Если ожидание отменяется, future *fut* также отменяется.

Эта функция является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine), пример использования:

```python
result = yield from asyncio.wait_for(fut, 60.0)
```

Изменено в версии 3.4.3: Если ожидание отменяется, future *fut* теперь также отменяется.
