在此document of Asyncio中,我们可以看到它使用await asyncio.sleep(1)
延迟了1秒,然后取消了任务。
我尝试将其更改为await asyncio.sleep(0)
,它也很好用。
但是,当我尝试删除await asyncio.sleep(1)
时,该程序似乎无法输入功能cancel_me
。因此它只出现在cli中的main(): cancel_me is cancelled now
。
这是什么原因?
答案 0 :(得分:1)
asyncio
协程不是自己执行的,而是由event loop执行的。
事件循环在asyncio.run
上接收控制权,并开始执行一些协程。当执行流达到await asyncio.sleep()
或await future
之类的阻塞时,它将控制权返回到事件循环。它允许事件循环开始或继续执行其他操作。
看看示例和图片here,看看简单的示例。
关于cancel()
的{{3}}中发生了以下情况:
await asyncio.sleep(0)
和1
会将控制权返回到事件循环cancel_me()
cancel_me()
最终会偶然发现某些阻塞,并将控制权返回给事件循环main()
main()
将使用task.cancel()
标记要取消的任务,并等待使用await task
取消任务但是,如果您在第一步中没有asyncio.sleep()
,则执行流程甚至都不会到达cancel_me()
,因为事件循环从未在任务创建和任务取消之间获得控制。当事件循环到达await task
时,它会看到任务从未启动,并标记为取消:现在就没有必要启动它。