asyncio中loop.create_task()创建的任务何时执行?代码示例解析
关于asyncio中
loop.create_task()任务执行时机的解答 问题1:loop.create_task()创建的任务何时执行?
当你用loop.create_task()(或者更推荐的asyncio.create_task(),二者核心逻辑一致)创建任务时,这个任务会被加入事件循环的待执行任务队列,但它不会立刻启动执行——事件循环只有在当前正在运行的协程主动让出控制权的节点,才会调度执行队列里的等待任务。
当前协程会让出控制权的常见场景包括:
- 调用
await等待一个可等待对象(比如asyncio.sleep()、其他协程、Future对象等) - 启动的根协程执行完毕,或是当前协程主动暂停
简单总结:任务被创建后会进入排队状态,直到当前“正在运行”的协程停下来“歇口气”(触发await操作),事件循环才会去处理队列里的等待任务。
问题2:给定代码中任务的执行时机分析
先贴出代码方便对照:
import asyncio async def task_func(): print('in task_func') return 'the result' async def main(loop): print('creating task') task = loop.create_task(task_func()) print('waiting for {!r}'.format(task)) await asyncio.sleep(2) return_value = await task print('task completed {!r}'.format(task)) print('return value: {!r}'.format(return_value)) event_loop = asyncio.new_event_loop() try: event_loop.run_until_complete(main(event_loop)) finally: event_loop.close()
我们一步步拆解执行流程:
- 事件循环启动,开始执行
main()协程:- 先打印
creating task - 调用
loop.create_task(task_func()),把task_func()包装成任务加入事件循环队列,但此时不会执行task_func()——因为当前main()协程还在持续运行,没有让出控制权 - 接着打印
waiting for <Task pending name='Task-1' coro=<task_func() running at ...>>
- 先打印
- 执行到
await asyncio.sleep(2):- 这时候
main()协程让出控制权,事件循环开始扫描待执行队列,找到刚创建的task_func()任务 - 事件循环执行
task_func(),打印in task_func,任务执行完成后返回结果,标记为“已完成”状态 - 随后事件循环进入等待状态,直到
asyncio.sleep(2)的2秒定时器到期
- 这时候
- 2秒后,
asyncio.sleep(2)执行完成,main()协程恢复运行:- 执行
await task,但此时任务已经完成,直接拿到返回值'the result' - 打印
task completed <Task finished name='Task-1' coro=<task_func() done, defined at ...> result='the result'> - 最后打印
return value: 'the result'
- 执行
这段代码的输出顺序为:
creating task waiting for <Task pending name='Task-1' coro=<task_func() running at ...>> in task_func # 等待2秒 task completed <Task finished name='Task-1' coro=<task_func() done, defined at ...> result='the result'> return value: 'the result'
内容的提问来源于stack exchange,提问作者Blaszard
相关产品推荐
相关产品推荐

