我开始学习python asyncio模块。我正在写一个基本的程序,它基本上是等待一段时间,然后打印结果。
async def say_helloworld(wait:int)->None:
print(f"starting say_helloworld({wait})")
await asyncio.sleep(wait)
print(f"say_helloworld({wait}) says hello world!")我编写了上面给出的协程,并创建了一些任务。
tasks = (asyncio.create_task(say_helloworld(i)) for i in range(10))然后,我将任务包装在另一个协程中。
async def main(tasks):
for task in tasks:
await task最后,我运行了包装器协程
asyncio.run(main(tasks))我的预期是程序将在大约10秒内完成,因为每个任务将同时等待,而不是以同步的方式。但是,程序几乎花了45秒(同步?)。我遗漏了什么?为什么它像同步程序一样运行?
发布于 2019-12-29 21:25:56
我按照上面给出的方式编写了协程,并创建了一些任务。
问题是你的代码,正如所写的,实际上并不是提前创建任务,它只是提供了一个在需要的时候如何创建任务的方法。tasks被初始化为:
tasks = (asyncio.create_task(say_helloworld(i)) for i in range(10))上面是一个生成器表达式,它只会在您迭代时创建任务。因此,虽然目的是提前创建任务,然后在它们并行运行时等待它们,但实际实现在每次迭代中创建单个任务,然后立即等待它。这会导致按顺序执行任务的不良结果。
修复方法是通过从(asyncio.create_task... )切换到[asyncio.create_task... ]来构建一个实际的列表。您还需要在协程中执行此操作,以便为任务运行一个事件循环。例如:
# ... say_helloworld defined as before ...
async def main():
tasks = [asyncio.create_task(say_helloworld(i)) for i in range(10)]
for task in tasks:
await task
asyncio.run(main())这导致了十个“开始...”消息之后只有一次停顿和十次“表示你好...”消息,这是最初的目标。
https://stackoverflow.com/questions/59518372
复制相似问题