`create_task()` 处的任务何时在 asyncio 中执行?
When is the task at `create_task()` executed in asyncio?
在下面的代码中:
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()
?
中加入事件循环后任务是什么时候执行的
Specifically, I assumed when you add a task to the event loop, it is executed soon, so I thought in task_func
is printed before waiting for <Task....
“即将执行”并不意味着立即执行。相反,您可以将其视为“我们一有机会就执行”,we 是事件循环。由于 print
紧跟在对 create_task
的调用之后,此时事件循环根本没有机会 运行。要让事件循环有机会 运行,您必须 return 进入事件循环,方法是从当前协程 return ing,或者等待阻塞的东西。
当你await
一个阻塞协程,比如asyncio.sleep()
,协程将暂时挂起并放弃对事件循环的控制。事件循环将查看在睡眠结束之前还有什么要做的,并将在其 运行 队列中找到使用 create_task
安排的任务。这就是为什么 task_func
和 task_func_2
在 main
协程等待睡眠时执行的原因 - 但不会在此之前执行,无论您是 await
他们特别还是其他什么块。
await
ing 协程如 task_func
意味着当场请求它的结果,并准备好在协程挂起时等待它。 (等待自动挂起的东西将执行推迟到事件循环,允许其他协程取得进展。)尽管实现不同,await
在概念上类似于 join
线程。
在下面的代码中:
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()
?
Specifically, I assumed when you add a task to the event loop, it is executed soon, so I thought
in task_func
is printed beforewaiting for <Task....
“即将执行”并不意味着立即执行。相反,您可以将其视为“我们一有机会就执行”,we 是事件循环。由于 print
紧跟在对 create_task
的调用之后,此时事件循环根本没有机会 运行。要让事件循环有机会 运行,您必须 return 进入事件循环,方法是从当前协程 return ing,或者等待阻塞的东西。
当你await
一个阻塞协程,比如asyncio.sleep()
,协程将暂时挂起并放弃对事件循环的控制。事件循环将查看在睡眠结束之前还有什么要做的,并将在其 运行 队列中找到使用 create_task
安排的任务。这就是为什么 task_func
和 task_func_2
在 main
协程等待睡眠时执行的原因 - 但不会在此之前执行,无论您是 await
他们特别还是其他什么块。
await
ing 协程如 task_func
意味着当场请求它的结果,并准备好在协程挂起时等待它。 (等待自动挂起的东西将执行推迟到事件循环,允许其他协程取得进展。)尽管实现不同,await
在概念上类似于 join
线程。