python - 如何在 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
这是可以实现的吗?如果是,我的代码有什么问题,我该如何解决?如果没有错误,是否有任何可能的方法来运行许多协程?
解决方案
您的代码有两个问题:
异步代码不能阻塞,所以
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())
推荐阅读
- c# - 运行更新数据库 entityframeworkcore 2 时出错
- angular - 服务器端渲染句柄身份验证
- material-ui - 使用主要、次要和错误之外的其他调色板
- angular - 试图从命名空间“Doctrine\Common\Cache”调用函数“apcu_fetch”
- android - 调用 DialogFragment 的活动:对话框并不总是被关闭
- xcode - React native:xcode 没有这样的文件或目录:libreact.a
- jquery - jQuery文件上传验证不起作用
- php - Homestead/Laravel 安装 LDAP 后显示白页
- dafny - 在 Dafny 中验证 Max 函数时违反断言?
- python - Python3.5 排序自定义比较无法按预期工作