繁体   English   中英

Python asyncio:任务是如何安排的?

[英]Python asyncio: how are tasks scheduled?

我是 Python asyncio 的新手,我正在做一些实验。 我有以下代码:

async def say_after(n, s):
    await asyncio.sleep(n)
    print(s)

async def main():
    task1 = asyncio.create_task(say_after(2, 'a'))
    task2 = asyncio.create_task(say_after(1, 'b'))
    await task1
    print('x', flush=True)
    await task2
    print('y', flush=True)

asyncio.run(main())

和 output:

b
a
x
y

我不明白这里的顺序。 有人可以帮忙解释一下吗? 特别是为什么 x 在 b 和 a 之后?

执行say_after (没有await )会创建一个协程 object,但还没有启动它

如果你在协程 object 上await那么你正在执行协程,直到 Python 在协程中遇到awaitreturn (或函数结束)之一。 这里的“执行”是指将协程转换为Task object 并将该任务 object 放入异步循环中。

但是, create_task立即“启动”协程并将它们放入异步循环中(不过,因为这是异步而不是并行,所以直到 Python 在main()中遇到await时才真正开始执行)。

在您的情况下,一旦 Python 看到await task1 task1 ,它就会“离开” main() 并在task1task2之间来回循环(因为这两个任务都已由 create_task 放入异步循环中)直到task1完成(因为 task1是正在等待的那个)。 因为 task2 已安排自己等待更短的时间,所以它首先完成。 大约 1 秒后,task1 完成,然后才返回到 main()(因为,请记住,main() 一直在等待 task1)。

此时, task1和task2都已经完成; await task2行实际上什么都不做; 它只是“结束” task2 并且(几乎)立即返回。

特别是为什么 x 在 b 和 a 之后?

bmain启动后约 1 秒打印在task2中,而amain启动后约 2 秒打印在task1中。 await task1等待task1 ,因此等待大约 2 秒。 因此,当await task1完成时, ba都会被打印出来。

(上面的“about”是故意的......会有变化,但在大多数情况下,它们会很小)

await task1基本上表示在task1完成之前不执行下一行代码(即执行say_after(2, 'a') )。

task1的执行时间比task2长,因此当您“等待” task1时, task2已经完成执行。 所以把await task2放在await task1 task1 下面有点没用。 如果交换这两行,则 output 将不同。

这就是为什么'b''a'之前打印的原因。 直到'a'被打印出来, 'x''y'才能被打印出来。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM