Bla*_*ard 4 python asynchronous python-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()
Run Code Online (Sandbox Code Playgroud)
当我执行代码时,结果如下:
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'
Run Code Online (Sandbox Code Playgroud)
但是我不明白您设置的代码何时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()
?
具体来说,我假设当您将一个任务添加到事件循环时,它很快就会执行,所以我认为
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
线程。