在这里完成newb,阅读有关Asycnio Tasks的信息,其中包含以下示例:
import asyncio
import time
async def say_after(delay, what):
await asyncio.sleep(delay)
print(what)
async def main():
task1 = asyncio.create_task(
say_after(1, 'hello'))
task2 = asyncio.create_task(
say_after(2, 'world'))
print(f"started at {time.strftime('%X')}")
# Wait until both tasks are completed (should take
# around 2 seconds.)
await task1
await task2
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())
我最初对await
的理解是,它会阻塞当前函数的执行,并等待异步函数返回。
但在这种情况下,两个协程都是并发执行的,这与我对await
的理解不太相符。有没有人能解释一下?
进一步的调查,通过在say_after
中添加额外的print
,在我看来,协程在await
发生之前是不会开始的……
import asyncio
import time
async def say_after(delay, what):
print('Received {}'.format(what))
await asyncio.sleep(delay)
print(what)
async def main():
task1 = asyncio.create_task(
say_after(1, 'hello'))
task2 = asyncio.create_task(
say_after(2, 'world'))
print(f"started at {time.strftime('%X')}")
# Wait until both tasks are completed (should take
# around 2 seconds.)
await task1
await task2
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())
打印
started at 13:41:23
Received hello
Received world
hello
world
finished at 13:41:25
发布于 2019-05-23 05:47:37
当您将协程封装在任务(或未来)对象中时,协程就可以工作了,因此当事件循环在第一个等待时开始运行时,task1和task2都在运行。
为了让它更清晰,为了执行协程,你需要做两件事:
1)封装在未来对象(任务)中的协程,以使其可等待
2)运行的事件循环
在您的示例中,执行过程如下所示:
1- create_task1
2- create_task2
3-等待task1
4-等待task1休眠
5-等待task2睡眠
现在task1和task2都在休眠,假设task1是第一个完成的(休眠一段时间)
6-打印task1
7-等待task2
8-打印task2
现在循环结束了
正如你所说的,当你得到一个等待时,执行就会停止,但我要说的是,它只是在当前的“执行流”中停止,当你创建一个未来(任务)时,你会创建另一个执行流,而等待只是切换到当前的执行流。最后一种解释在意义上并不完全正确,但有助于使其更清晰。
我希望我说得够清楚了。附言:对不起,我的英语不好。
发布于 2019-05-23 05:27:40
你对等待的理解是正确的。它会暂停main函数的执行。
关键是asyncio.create_task()
创建任务并对其进行调度。
因此,say_after
函数从这里开始运行:
task1 = asyncio.create_task(
say_after(1, 'hello'))
task2 = asyncio.create_task(
say_after(2, 'world'))
而不是在你等待的时候。
查看此处:https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task
发布于 2019-05-28 06:48:17
好的,@tsuyoku和@Fanto的答案都是正确的,这个答案只是对现有答案的补充,对我来说,我不能掌握的重要一点是在create_task()
上开始执行
import asyncio
import time
async def say_after(delay, what):
print('Received {}'.format(what))
await asyncio.sleep(delay)
print(what)
async def main():
task1 = asyncio.create_task(
say_after(1, 'hello')
)
task2 = asyncio.create_task(
say_after(2, 'world')
)
print(f"started at {time.strftime('%X')}")
await asyncio.sleep(10)
# Wait until both tasks are completed (should take
# around 2 seconds.)
await task2
print('task 2 finished')
await task1
print('task 1 finished')
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())
打印
started at 10:42:10
Received hello
Received world
hello
world
task 2 finished
task 1 finished
finished at 10:42:20
最初的误解是,内容需要一些时间来运行任务,而我问题中的原始打印输出误导了我,使我误以为任务在await
语句之前不会运行。
https://stackoverflow.com/questions/56265166
复制相似问题