python如何绕过我之前的代码,先运行后面的代码?

2024-05-13 07:29:37 发布

您现在位置:Python中文网/ 问答频道 /正文

import asyncio
import time


async def func():
    print('task start')
    await asyncio.sleep(10)
    print('task end')


async def main():
    task1 = asyncio.create_task(func())
    task2 = asyncio.create_task(func())
    task3 = asyncio.create_task(func())
    task4 = asyncio.create_task(func())
    s = time.monotonic()
    print('main start', time.monotonic() - s)
    await task1
    print('main continue', time.monotonic() - s)
    await task2
    print('main continue', time.monotonic() - s)
    await task3
    print('main continue', time.monotonic() - s)
    await task4
    print('main end', time.monotonic() - s)


asyncio.run(main())

该代码给出如下结果:

main start 0.0
task start
task start
task start
task start
task end
task end
task end
task end
main continue 10.0
main continue 10.0
main continue 10.0
main end

但是这怎么可能呢python绕过了我之前的打印调用, 先运行等待列表,然后返回打印通话, 我该如何理解这一点


Tags: importasynciotaskasynctimemaindefcreate
2条回答

您的代码按照asyncio的规范执行它应该执行的操作,但可能您误解了“任务”是什么

从文档中:

asyncio.create_task(coro, *, name=None)

Wrap the coro coroutine into a Task and schedule its execution. Return the Task object.

这意味着,当您在主任务开始时创建了4个任务时,它们都计划在同一时间开始执行。因此,它们都一起打印task start,然后一起打印task end,在这一点上,所有的await都会立即失败,因为所有任务都在同一时间完成(10秒后)。最后你看到了main continue 10.03次

试试这个代码,我相信它会有你期望的行为

async def main():
    task1 = func()
    task2 = func()
    task3 = func()
    task4 = func()
    ...

你所有的任务都是睡眠10秒,然后继续并几乎立即完成。 因此,所有的await调用将同时解锁,因为当任务1完成时,所有任务也将完成

你是对的,从技术上讲,你可以在task endmain continue之间有相互交织的打印,但我想这是一个实现细节,所有内容似乎都是分组的

我认为您可以通过使用此经过调整的脚本更好地了解正在发生的事情:

import asyncio
import time


async def func(task_nb, wait):
    print('[%s] task start' % task_nb)
    await asyncio.sleep(wait)
    print('[%s] task end' % task_nb)


async def main():
    task1 = asyncio.create_task(func(1, 1))
    task2 = asyncio.create_task(func(2, 5))
    task3 = asyncio.create_task(func(3, 7))
    task4 = asyncio.create_task(func(4, 2))
    s = time.monotonic()
    print('main start', time.monotonic() - s)
    await task1
    print('main continue', time.monotonic() - s)
    await task2
    print('main continue', time.monotonic() - s)
    await task3
    print('main continue', time.monotonic() - s)
    await task4
    print('main end', time.monotonic() - s)


asyncio.run(main())

您将有一个更有趣的await行为:

main start 1.81000359589234e-07
[1] task start
[2] task start
[3] task start
[4] task start
[1] task end
main continue 1.0019499360005284
[4] task end
[2] task end
main continue 5.001785704000213
[3] task end
main continue 7.003587035000237
main end 7.003632674000073

相关问题 更多 >