何时在异步执行`create_task()`上的任务? [英] When is the task at `create_task()` executed in asyncio?
问题描述
在以下代码中:
导入异步异步def task_func():打印('在task_func')返回结果"异步def main(循环):打印(正在创建任务")任务= loop.create_task(task_func())print('正在等待{!r}'.format(task))等待asyncio.sleep(2)return_value =等待任务print('任务完成{!r}'.format(task))print('返回值:{!r}'.format(return_value))event_loop = asyncio.new_event_loop()尝试:event_loop.run_until_complete(main(event_loop))最后:event_loop.close()
执行代码时,结果如下:
创建任务等待<任务待定coro =< task_func()在< ipython-input-29-797f29858344>:>>上运行".在task_func中任务已完成`<任务已完成coro =< task_func()完成,在< ipython-input-29-797f29858344>:1>中定义result ='结果'>`返回值:结果"
但是我不明白何时执行在 loop.create_task(task_func())
中设置的代码.具体来说,我假设将任务添加到事件循环时,该任务很快就会执行,因此我认为在等待< Task ...
之前先打印task_func 中的.
然后我发现它总是在等待< Task ...
之后执行,因此我添加了 await asyncio.sleep(2)
,但仅发现2秒结束之前已打印task_func 中的.
我还添加了 task_func_2()
,它实际上与 task_func()
相同,并在 task = loop.create_task(task_func())下创建其任务.
,但不要添加 return_value_2 = await task2
,因此 await
不会执行任务(否则, task_func_2()
永远不会执行).
所以现在我被搞糊涂了.将任务添加到 loop.create_task()
中的事件循环后,何时执行任务?
具体来说,我假设将任务添加到事件循环时,该任务很快就会执行,因此我认为在
等待< Task ....之前打印出task_func
中的./code>
即将执行"并不意味着立即执行.相反,您可以将其视为执行了获得的第一个机会",我们是事件循环.由于 print
立即跟随对 create_task
的调用,因此事件循环还没有机会运行.为了使事件循环有运行的机会,您必须返回到事件循环,方法是从当前协程返回,或者等待阻塞的事件.
当您 await
阻塞的协程(例如 asyncio.sleep()
)时,协程将暂时挂起自身并放弃对事件循环的控制.事件循环将查看睡眠结束之前还有什么要做,并在其运行队列中找到使用 create_task
安排的任务.这就是为什么当 main
协程等待睡眠时执行 task_func
和 task_func_2
的原因-但在此之前,并且无论您是否等待
特别是它们或其他阻塞的东西.
等待
一个协程,例如 task_func
意味着在那儿然后在那里请求它的结果,并准备等待它.(这种等待会自动将执行推迟到事件循环,从而允许其他协程取得进展.)尽管实现有所不同,但是 await
在概念上类似于 join
线程./p>
In the following code:
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()
When I execute the code, the result is the following:
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'
But I don't understand when the code you set at loop.create_task(task_func())
is executed. 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...
.
Then I found it is always executed after the waiting for <Task...
, so I added await asyncio.sleep(2)
, but only found that the in task_func
is printed before the finish of 2 seconds.
I also added task_func_2()
which is practically the same as task_func()
and create its task below task = loop.create_task(task_func())
but do NOT add return_value_2 = await task2
, so the await
does not execute the task (otherwise the task_func_2()
is never executed).
So now I got confuesed. When is the task is executed after it is added to the event loop in 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....
"Executed soon" doesn't mean executed right away. Instead, you can think of it as "executed the first chance we get," we being the event loop. Since print
immediately follows the call to create_task
, at that point the event loop hasn't yet had a chance to run at all. To give event loop a chance to run, you must return to the event loop, either by returning from the current coroutine, or by awaiting something that blocks.
When you await
a blocking coroutine such as asyncio.sleep()
, the coroutine will temporarily suspend itself and relinquish control to the event loop. The event loop will look at what else there is to do before the sleep elapses and will find the tasks scheduled using create_task
in its run queue. This is why task_func
and task_func_2
are executed when the main
coroutine awaits the sleep - but not before that, and regardless of whether you await
them in particular or something else that blocks.
await
ing a coroutine such as task_func
means requesting its result then and there, and being prepared to wait for it. (Such wait automatically defers execution to the event loop, allowing other coroutines to make progress.) Although the implementation differs, an await
is conceptually similar to join
ing a thread.
这篇关于何时在异步执行`create_task()`上的任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!