在以下代码中:
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_2()
,它与task_func()
几乎相同,并在task = loop.create_task(task_func())
下面创建了任务但不添加return_value_2 = await task2
,因此await
会不执行任务(否则永远不会执行task_func_2()
)。
所以现在我被困惑了。何时将任务添加到loop.create_task()
?
答案 0 :(得分:5)
具体来说,我假设你在事件循环中添加一个任务时很快就会执行,所以我认为在
in task_func
之前打印waiting for <Task....
“尽快执行”并不意味着马上执行。相反,你可以把它想象成“我们得到的第一次机会”,我们是事件循环。由于print
紧跟在create_task
的调用之后,此时事件循环还没有机会运行。要为事件循环提供运行机会,必须返回事件循环,方法是从当前协程返回,或等待阻塞的东西。
当您await
阻塞协程如asyncio.sleep()
时,协程将暂时暂停并放弃对事件循环的控制。事件循环将查看在睡眠过去之前还要做的其他事情,并将在其运行队列中找到使用create_task
计划的任务。这就是为什么task_func
和task_func_2
在main
协程等待睡眠时执行的原因 - 而不是在此之前执行,而不管您是否特别await
或其他块。
await
诸如task_func
之类的协程意味着在那时请求其结果,并准备等待它。 (这种等待会自动将执行推迟到事件循环,允许其他协同程序取得进展。)虽然实现方式不同,但await
在概念上类似于join
一个线程。