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绕过了我之前的打印调用, 首先运行等待对象,然后返回以进行打印呼叫, 我该如何理解?
答案 0 :(得分:1)
您的所有任务都在休眠10秒钟,然后继续并几乎立即完成。
因此,自任务1完成后,所有await
调用将同时解锁,所有任务也将完成。
从技术上来说,您可以在task end
和main 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
答案 1 :(得分:0)
您的代码按照asyncio
的说明执行了应做的事情,但是也许您误解了“任务”是什么。
从文档中
asyncio.create_task(coro, *, name=None)
将coro协程包装到Task中并安排其执行时间。返回Task对象。
这意味着当您在主程序的开头创建了4个任务时,它们都计划在同一时间开始执行。因此,他们一起打印task start
,然后一起打印task end
,这时,所有任务同时完成(10秒后),所有await
都会立即掉线)。所以最后您看到main continue 10.0
3次。
尝试此代码,我相信它将具有您期望的行为。
async def main():
task1 = func()
task2 = func()
task3 = func()
task4 = func()
...