Парализовать несколько вызовов асинхронной функции - PullRequest
1 голос
/ 11 марта 2020

У меня есть следующий сценарий:

from time import sleep

async def do_a(a):
    sleep(0.001)
    return 1*a

async def do_b(a):
    sleep(0.01)
    return 2*a

async def do_c(b):
    sleep(1)
    return 3*b


async def my_func():
    results = []
    for i in range(3):
        a = await do_a(i)
        b = await do_b(a)
        c = await do_c(b)
        results.append(c)
    return results

if __name__ == "__main__":
    import asyncio
    print(asyncio.run(my_func()))

По сути, я вызываю асинхронные функции в al oop. Выполнение приведенного выше кода показывает, что он выполняется в ~ 3 с. Я хотел бы вызывать каждую процедуру параллельно, поэтому ожидаемое время упадет до ~ 1 с (я знаю, что эти издержки слишком оптимистичны c, но для оптимизации времени выполнения хотя бы немного). Я искал разные python библиотеки, которые, как мне кажется, могли бы помочь, но не мог решить, какая из них полезна в этом случае. * * * * * * * * * * * * * * * * * * * - многопроцессорность, многопоточность и параллелизм. Все они, похоже, реализуют ту или иную форму параллелизма / параллелизма. Что мне делать? Можете ли вы показать мне, как вы будете действовать в этом случае?

1 Ответ

3 голосов
/ 11 марта 2020

Вы должны использовать asyncio.sleep вместо time.sleep. Если вы хотите, чтобы все выполнялось одновременно, это можно сделать одним способом: asyncio.gather:

import asyncio

async def do_a(a):
    await asyncio.sleep(0.001)
    return 1*a

async def do_b(a):
    await asyncio.sleep(0.01)
    return 2*a

async def do_c(b):
    await asyncio.sleep(1)
    return 3*b

async def do_abc(i):
    a = await do_a(i)
    b = await do_b(a)
    return await do_c(b)

async def my_func():
    return await asyncio.gather(*map(do_abc, range(3)))

if __name__ == "__main__":
    import asyncio
    print(asyncio.run(my_func()))
    # [0, 6, 12]

Если реальный код, который выполняется вместо sleep, является синхронным ( блокирование), вы будете делать по сути то же самое, только вам придется отложить эту работу до исполнителя .

...