为什么我们需要`Asyncio.sleep`来开始循环?

时间:2019-03-31 04:32:09

标签: python-3.x python-asyncio

在此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

这是什么原因?

1 个答案:

答案 0 :(得分:1)

asyncio协程不是自己执行的,而是由event loop执行的。

事件循环在asyncio.run上接收控制权,并开始执行一些协程。当执行流达到await asyncio.sleep()await future之类的阻塞时,它将控制权返回到事件循环。它允许事件循环开始或继续执行其他操作。

看看示例和图片here,看看简单的示例。


关于cancel()的{​​{3}}中发生了以下情况:

  1. await asyncio.sleep(0)1会将控制权返回到事件循环
  2. 事件循环将开始执行cancel_me()
  3. cancel_me()最终会偶然发现某些阻塞,并将控制权返回给事件循环
  4. 事件循环将恢复执行main()
  5. main()将使用task.cancel()标记要取消的任务,并等待使用await task取消任务

但是,如果您在第一步中没有asyncio.sleep(),则执行流程甚至都不会到达cancel_me(),因为事件循环从未在任务创建和任务取消之间获得控制。当事件循环到达await task时,它会看到任务从未启动,并标记为取消:现在就没有必要启动它。