异步收集调度顺序保证

pbn*_*pbn 9 python python-asyncio

是否保证作为参数的协程asyncio.gather将按照保留的顺序进行调度?考虑以下示例:

import asyncio

async def coro(i):
    print('{i} finished'.format(i=i))

async def main():
    await asyncio.gather(
            coro(0),
            coro(1),
            coro(2),
            coro(3),
            coro(4),
    )

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)

结果:

0 finished
1 finished
2 finished
3 finished
4 finished
Run Code Online (Sandbox Code Playgroud)

Vla*_*den 13

来自 Python 文档

awaitable asyncio.gather(*aws, loop=None, return_exceptions=False)

同时运行 aws 序列中的可等待对象。

如果 aws 中的任何 awaitable 是协程,则它会自动安排为任务。

如果所有 awaitable 都成功完成,则结果是返回值的聚合列表。结果值的顺序对应于 aws 中等待的顺序。

所以结果值的顺序被保留,但执行顺序不是。


Pro*_*osh 4

是的,至少从cpython实现的源码来看,它们是按照顺序来安排的。迭代协同例程列表,并将一个任务逐一添加到每个协同例程的循环中。虽然我没有看到调度保证在哪种情况下变得重要。不能保证循环将按顺序执行它们,也不能保证它们将按该顺序完成。我认为这将取决于特定循环的实现细节和代码的性质。例如,尝试在打印之前将 asyncio.sleep(1) 添加到协同例程中。