为何使用asyncio.wait仅等待task2时,未被加入等待列表的task1仍会执行?
为什么未加入
asyncio.wait列表的task1依然会执行? 这是个很常见的asyncio入门困惑,核心原因在于**asyncio.create_task()的本质:一旦你调用这个函数,任务就已经被提交到事件循环中,会自动开始运行,和你有没有用asyncio.wait()去等待它完全无关**。
我来拆解下你的代码逻辑:
- 当你执行
task1 = asyncio.create_task(say_after(1, 'hello'))时,事件循环已经把这个任务排上了日程,它会在后台开始等待1秒,然后打印"hello"——这个过程不需要你手动去await它或者把它加入wait的列表。 - 而
asyncio.wait(aws)的作用只是:暂停当前协程(main),直到aws列表里的所有任务完成。它不会控制其他已经被提交到事件循环的任务的生死。
回到你的第一个场景:
你只让wait等待task2(需要2秒),但task1只需要1秒就能完成。所以在这2秒的等待过程中,task1已经跑完了,自然会打印"hello"。等task2完成后,main函数结束,事件循环才会退出。
第二个场景里你把task1也加入了wait列表,不过因为task1的耗时比task2短,wait最终还是会等2秒(task2的耗时),所以输出的结束时间和第一个场景一致,看起来差别不大,但本质上wait此时是在等待两个任务都完成,而第一个场景里wait只等task2,task1是自己在后台跑完的。
如果想让task1不执行,你有两个选择:
- 不要用
asyncio.create_task(),只是创建协程对象:task1 = say_after(1, 'hello'),这样它不会被提交到事件循环,自然不会运行。 - 如果已经用
create_task创建了task1,可以调用task1.cancel()来取消它,这样它就不会执行了。
内容的提问来源于stack exchange,提问作者xjlin
相关产品推荐
相关产品推荐

