我试图理解python asyncio lib,但这很痛苦,每次我认为我知道代码的行为方式时,都会感到有些惊讶。
我有以下代码:
async def a():
while True:
task = asyncio.current_task() # asyncio.Task.current_task()
print(task.name)
await asyncio.sleep(0.5)
async def main():
tasks = []
for i in range(10):
c = a()
task = asyncio.create_task(c)
task.name = "task nr {}".format(i)
tasks.append(task)
for task in tasks:
await task
asyncio.run(main())
怀疑会产生以下结果的结果:
task nr 0
task nr 1
task nr 2
task nr 3
task nr 4
task nr 5
task nr 6
task nr 7
task nr 8
task nr 9
,依此类推。 另一方面,我有一个代码
async def a():
while True:
task = asyncio.current_task() # asyncio.Task.current_task()
print(task.name)
await asyncio.sleep(0.5)
async def main():
for i in range(10):
c = a()
task = asyncio.create_task(c)
task.name = "task nr {}".format(i)
await task
asyncio.run(main())
这一次它只输出“任务nr 0”。
在第一个任务中创建10个任务,然后将所有任务都标上星标。第二个合并了这两个循环-为什么它会影响程序的行为?
答案 0 :(得分:2)
您的a()
是无限协程。等待它的过程将从不完成。意味着在您的第二个摘录中,for
循环将永远不会进入下一个迭代。基本上,它在await task
上永远被“阻止”。
答案 1 :(得分:1)
第二个合并了这两个循环-为什么它会影响程序的行为?
因为您的第一个代码在进入await
之前针对所有十个协程运行create_task
。
由于create_task
安排了协程的执行,在第一个示例中,当您等待第一个协程时,所有十个协程都愉快地并行执行(作为另一个答案points out,它将永远不会完整,因为协程是无限的)。在第二个循环中,您只在无限等待之前执行一个 create_task
,因此您只能运行一个协程。
如果您熟悉线程,也许可以使用以下类比来帮助您:您可以将create_task
视为产生线程,而将await
视为加入线程。在第一个示例中,您生成了十个,在第二个示例中,仅生成了一个。