Функция create_task()



Функция asyncio.create_task(coro) оборачивает сопрограмму в задачу (task) и планирует её выполнение. Эта функция возвращает объект типа <class ‘_asyncio.Task’>. Вы уже видели примеры использования задач в коде. Вы можете запланировать выполнение любого количества задач; именно этот механизм помогает нам создавать большое количество задач для наших сопрограмм.

Код ниже показывает элементарный пример создания двух задач. Обратите внимание, что функция принимает в качестве аргументов сопрограммы one() и two(). Этот пример не совсем отображает принцип асинхронного выполнения, так как в нём нет блокирующих команд. Всё происходит по порядку: сначала печатается «1», затем «2».

import asyncio

async def two(x):
    print(x)

async def one(x):
    print(x)

async def main():
    task1 = asyncio.create_task(one(1))
    task2 = asyncio.create_task(two(2))
    await task1
    await task2

asyncio.run(main())

#Результат

   1
   2

Теперь добавим в эти сопрограммы элемент случайности. А именно, встроенную сопрограмму asyncio.sleep(), которая помогает сопрограмме случайным образом «заснуть» на период от одной до шести секунд, тем самым имитируя выполнение I/O bound операции. При запуске этого кода несколько раз результат будет зависеть от того, какая сопрограмма «спит» дольше. Пока одна сопрограмма спит, управление передаётся другой. Об этом говорит оператор await.

import asyncio
import random

async def two(x):
    await asyncio.sleep(random.randint(1, 6))
    print(x)

async def one(x):
    await asyncio.sleep(random.randint(1, 6))
    print(x)

async def main():
    task1 = asyncio.create_task(one(1))
    task2 = asyncio.create_task(two(2))
    await task1
    await task2

asyncio.run(main())

Добавим немного итераций в код. Каждая сопрограмма будет выполнена по пять раз, «засыпая» на случайное время. Здесь уже лучше видно, как работает асинхронность, потому что у нас уже есть результат, отображающий ход выполнения асинхронного кода. При запуске этого кода результат будет всегда разный.

import asyncio
import random

async def two(x):
    await asyncio.sleep(random.randint(1, 3))
    print(x)

async def one(x):
    await asyncio.sleep(random.randint(1, 3))
    print(x)

async def main():
    for x in range(5):
        task1 = asyncio.create_task(one(1))
        task2 = asyncio.create_task(two(2))
        await task1
        await task2

asyncio.run(main())

#Результат
    1
    2
    2
    1
    1
    2
    2
    1
    1
    2

Такой подход не очень удобен, потому что вы не можете создавать отдельный таск на каждый запрос — это заняло бы кучу времени и убило бы всё удовольствие от программирования. Для этого существуют две основные функции — asyncio.gather() и asyncio.wait(). Забегая вперед, отмечу, что они отлично работают с объектами ожидания, которыми и являются таски.



Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: