"create_task()"处的任务何时在异步中执行?



在下面的代码中:

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()

当我执行代码时,结果如下:

creating task
waiting for `<Task pending coro=<task_func() running at <ipython-input-29-797f29858344>:1>>`
in task_func
task completed `<Task finished coro=<task_func() done, defined at <ipython-input-29-797f29858344>:1> result='the result'>`
return value: 'the result'

但是我不明白您在loop.create_task(task_func())设置的代码何时执行。具体来说,我假设当您将任务添加到事件循环时,它很快就会执行,所以我认为in task_func是在waiting for <Task...之前打印的。

然后我发现它总是waiting for <Task...后执行,所以我加了await asyncio.sleep(2),但只发现in task_func是在 2 秒结束之前打印的。

我还添加了实际上与task_func()相同的task_func_2(),并在task = loop.create_task(task_func())下面创建其任务,但不添加return_value_2 = await task2,因此await不会执行任务(否则永远不会执行task_func_2()(。

所以现在我感到困惑。任务添加到loop.create_task()中的事件循环后何时执行?

具体来说,我假设当您将任务添加到事件循环时,它很快就会执行,所以我认为in task_funcwaiting for <Task....之前打印

"很快被处决"并不意味着立即被处决。相反,你可以把它想象成"我们得到的第一个机会就执行",我们就是事件循环。由于print紧跟在对create_task的调用之后,此时事件循环根本没有机会运行。若要使事件循环有机会运行,必须返回到事件循环,方法是从当前协程返回,或者等待阻塞的内容。

当您await阻塞协程(如asyncio.sleep()(时,该协程将暂时挂起自身并将控制权交给事件循环。事件循环将查看在睡眠结束之前还有什么要做,并在其运行队列中找到使用create_task计划的任务。这就是为什么task_functask_func_2main协程等待睡眠时执行的原因 - 但在此之前不是,无论您是否特别await它们还是其他阻塞的东西。

await协程(如task_func(意味着当时和那里请求其结果,并准备好在协程挂起时等待它。(等待挂起的内容会自动将执行推迟到事件循环,从而允许其他协程取得进展。尽管实现不同,但await在概念上类似于join线程。

最新更新