Soru Çalışan bir asyncio döngüsüne nasıl bir coroutine eklenir?


Çalışan bir asyncio döngüsüne nasıl yeni bir coroutine eklenebilir? Yani. zaten bir dizi koroutini yürüten biri.

Bir geçici çözüm olarak, varolan ortak yordamların tamamlanmasını ve ardından yeni bir döngü başlatmasını (ek coroutine ile) bekleyebilirim. Ama daha iyi bir yolu var mı?


17
2017-12-28 19:20


Menşei




Cevaplar:


Kullanabilirsiniz create_task yeni koroutinler planlamak için:

import asyncio

async def cor1():
    ...

async def cor2():
    ...

async def main(loop):
    await asyncio.sleep(0)
    t1 = loop.create_task(cor1())
    await cor2()
    await t1

loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
loop.close()

11
2017-12-28 19:59



Çaba için teşekkürler, ama anladığım kadarıyla, bu cevap yanlış. İşte ilk girişimi main Koroutini oluşturur ve döngü bundan sonra başlar. Başka bir deyişle, bu örnek, döngü başlamadan önce koroutinleri planlar. İstediğim şey bu değil. - Petri
main sadece bir sarıcı olarak orada; Sadece işaret etmek istedim loop.create_taskkullanımı. create_task tam olarak istediğini yapar. - Bunu açıklığa kavuşturmak için örneği düzenledim main çalıştırmadan önce bloke olur create_task. - Jashandeep Sohi
arayamazsın loop.run_until_complete() döngü çalışırken - Lei Zhang


Zaten çalışan bir etkinlik döngüsüne bir işlev eklemek için şunları kullanabilirsiniz:

asyncio.ensure_future(my_coro())

Benim durumumda multithreading kullanıyordum (threading) yanında asyncio ve zaten çalışmakta olan olay döngüsüne bir görev eklemek istedim. Aynı durumdaki herkes için, etkinlik döngüsünü açıkça belirtin (içeriğin içinde olmadığı gibi). Thread). yani:

Küresel kapsamda:

event_loop = asyncio.get_event_loop()

Sonra daha sonra Thread:

asyncio.ensure_future(my_coro(), loop=event_loop)

10
2017-10-12 13:23





Sorunuz "Çalışan programa nasıl çağrılır?" Sorusuna çok yakındır.

Tam olarak ne zaman olay döngüsüne yeni coroutine eklemeniz gerekiyor?

Biraz örnek görelim. Burada olay döngüsünü iki koroutinle birlikte başlatan program:

import asyncio
from random import randint


async def coro1():
    res = randint(0,3)
    await asyncio.sleep(res)
    print('coro1 finished with output {}'.format(res))
    return res

async def main():
    await asyncio.gather(
        coro1(),
        coro1()
    ) # here we have two coroutines running parallely

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

Çıktı:

coro1 finished with output 1
coro1 finished with output 2
[Finished in 2.2s]

Sonuç alabilecek bazı koroutinler eklemeniz gerekebilir. coro1 ve en kısa sürede hazır mı? Bu durumda sadece beklemekte olan coroutine yaratın coro1 ve geri dönen değeri kullanın:

import asyncio
from random import randint


async def coro1():
    res = randint(0,3)
    await asyncio.sleep(res)
    print('coro1 finished with output {}'.format(res))
    return res

async def coro2():
    res = await coro1()
    res = res * res
    await asyncio.sleep(res)
    print('coro2 finished with output {}'.format(res))
    return res

async def main():
    await asyncio.gather(
        coro2(),
        coro2()
    ) # here we have two coroutines running parallely

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

Çıktı:

coro1 finished with output 1
coro2 finished with output 1
coro1 finished with output 3
coro2 finished with output 9
[Finished in 12.2s]

Koroutini, özel sözdizimi olan normal işlevler hakkında düşünün. Paralel olarak yürütmek için bazı işlevler kümesine başlayabilirsiniz. asyncio.gather), ilk bittikten sonra sonraki işlevi başlatabilir, başkalarını arayarak yeni fonksiyonlar yaratabilirsiniz.


8
2017-12-30 08:21



Coroutines koş eş zamanlı olarak, değil paralel. Tam olarak aynı şey değil. - Gustavo Bezerra