[英]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 在协程中遇到await
或return
(或函数结束)之一。 这里的“执行”是指将协程转换为Task
object 并将该任务 object 放入异步循环中。
但是, create_task
立即“启动”协程并将它们放入异步循环中(不过,因为这是异步而不是并行,所以直到 Python 在main()
中遇到await
时才真正开始执行)。
在您的情况下,一旦 Python 看到await task1
task1 ,它就会“离开” main() 并在task1
和task2
之间来回循环(因为这两个任务都已由 create_task 放入异步循环中)直到task1
完成(因为 task1是正在等待的那个)。 因为 task2 已安排自己等待更短的时间,所以它首先完成。 大约 1 秒后,task1 完成,然后才返回到 main()(因为,请记住,main() 一直在等待 task1)。
此时, task1和task2都已经完成; await task2
行实际上什么都不做; 它只是“结束” task2 并且(几乎)立即返回。
特别是为什么 x 在 b 和 a 之后?
b
在main
启动后约 1 秒打印在task2
中,而a
在main
启动后约 2 秒打印在task1
中。 await task1
等待task1
,因此等待大约 2 秒。 因此,当await task1
完成时, b
和a
都会被打印出来。
(上面的“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.