首页 > 解决方案 > 如何在 Python asyncio 中将新的协同程序添加到已经运行的循环中?

问题描述

我写了这样的代码。

import asyncio
import time
import random

async def secondCoro(myId):
    waiting_time = random.randint(1,5)
    while 1:
        print("i am {} ".format(myId))
        time.sleep(waiting_time)


async def main():
    for i in range (10):
        await loop.create_task(secondCoro(i))
        time.sleep(0.1)

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

我需要同时运行 10 个协程。我给了随机的睡眠时间,所以我认为它会像这样显示输出。

i am 0

i am 2

i am 4

i am 1

i am 2

i am 8

i am 5

但是当我运行这段代码时,它只显示,

i am 0

i am 0

i am 0

这是可以实现的吗?如果是,我的代码有什么问题,我该如何解决?如果没有错误,是否有任何可能的方法来运行许多协程?

标签: pythonpython-3.xpython-asyncio

解决方案


您的代码有两个问题:

  • 异步代码不能阻塞,所以time.sleep()你必须等待而不是调用asyncio.sleep()

  • “await”的意思是“等到完成”,所以当你在 main() 中等待循环中的任务时,你永远不会超过循环的第一次迭代,因为任务永远不会完成。

有几种方法可以解决第二个问题。例如,您可以调用asyncio.gather(),或者您可以保持循环原样,但省略任务的等待,而是在第二个循环中等待它们。例如:

async def secondCoro(myId):
    waiting_time = random.randint(1,5)
    while True:
        print("i am {} ".format(myId))
        await asyncio.sleep(waiting_time)

async def main():
    # start all the tasks
    tasks = [asyncio.create_task(secondCoro(i)) for i in range(10)]
    # and await them, which will basically wait forever, while still
    # allowing all the tasks to run
    for t in tasks:
        await t

asyncio.run(main())

推荐阅读