Python asyncio任务无法启动

时间:2018-11-18 21:28:25

标签: python concurrency python-asyncio

我试图理解python asyncio lib,但这很痛苦,每次我认为我知道代码的行为方式时,都会感到有些惊讶。

我有以下代码:

async def a():
    while True:
        task = asyncio.current_task()  # asyncio.Task.current_task()
        print(task.name)
        await asyncio.sleep(0.5)

async def main():
    tasks = []

    for i in range(10):
        c = a()
        task = asyncio.create_task(c)
        task.name = "task nr {}".format(i)
        tasks.append(task)

    for task in tasks:
        await task

asyncio.run(main())

怀疑会产生以下结果的结果:

task nr 0
task nr 1
task nr 2
task nr 3
task nr 4
task nr 5
task nr 6
task nr 7
task nr 8
task nr 9

,依此类推。 另一方面,我有一个代码

async def a():
    while True:
        task = asyncio.current_task()  # asyncio.Task.current_task()
        print(task.name)
        await asyncio.sleep(0.5)

async def main():

    for i in range(10):
        c = a()
        task = asyncio.create_task(c)
        task.name = "task nr {}".format(i)
        await task

asyncio.run(main())

这一次它只输出“任务nr 0”。

在第一个任务中创建10个任务,然后将所有任务都标上星标。第二个合并了这两个循环-为什么它会影响程序的行为?

2 个答案:

答案 0 :(得分:2)

您的a()是无限协程。等待它的过程将从不完成。意味着在您的第二个摘录中,for循环将永远不会进入下一个迭代。基本上,它在await task上永远被“阻止”。

答案 1 :(得分:1)

  

第二个合并了这两个循环-为什么它会影响程序的行为?

因为您的第一个代码在进入await之前针对所有十个协程运行create_task

由于create_task安排了协程的执行,在第一个示例中,当您等待第一个协程时,所有十个协程都愉快地并行执行(作为另一个答案points out,它将永远不会完整,因为协程是无限的)。在第二个循环中,您只在无限等待之前执行一个 create_task,因此您只能运行一个协程。

如果您熟悉线程,也许可以使用以下类比来帮助您:您可以将create_task视为产生线程,而将await视为加入线程。在第一个示例中,您生成了十个,在第二个示例中,仅生成了一个。