异步事件循环是否仅运行任务?

时间:2020-05-17 15:06:59

标签: python python-3.x python-asyncio

我正处于学习异步库的早期阶段。我从协程和任务开始,并通读docs中的 hello world 示例。

根据有关协程的部分,似乎有两种主要方法来运行协程对象:

  • 在协同程序上使用await
  • 将协程作为异步Tasks

根据Task文档:

任务用于在事件循环中运行协程。

要清楚一点,这是否意味着除非将事件包装到任务中,否则事件循环不会运行协程对象?在这种情况下,这些协程对象是否只是同步运行而没有与事件循环发生任何交互?

1 个答案:

答案 0 :(得分:1)

要清楚一点,这(用于任务运行协程)是否意味着事件循环除非将它们包装到任务中,否则不会运行协程对象?

这意味着任务是协程世界的切入点。每个协程都可以追溯到外部协程正在等待,一直到由任务驱动的协程。

使用以下示例代码:

async def inner():
    await asyncio.sleep(1)

async def outer():
    await inner()
    await inner()

async def main():
    await outer()

asyncio.run(main())

asyncio.run隐式创建一个任务来驱动main协程完成。该任务仅“看到”通过调用main()创建的协程对象,与协程main等待无关。从任务的角度来看,main将暂停两次,每个sleep暂停一次。在暂停之前,sleep协程将与事件循环一起安排要恢复的任务。

在这种情况下,这些协程对象是否只是同步运行而没有与事件循环发生任何交互?

所有协程必须与事件循环交互,因为它们必须能够暂停。如果它们被另一个协程等待,它们会导致等待的协程暂停。这会传播到由任务运行的顶级协程,从而导致任务挂起。