F.E*_*F.E 6 python asynchronous
我试图了解 pythons asynico 模块并在https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task 上遇到了以下代码
import time
import asyncio
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('started at', time.strftime('%X'))
# Wait until both tasks are completed (should take
# around 2 seconds.)
await task1
await task2
print('finished at', time.strftime('%X'))
asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)
事实证明, await task2, (或task1,但不是两者)可以简单地删除,并且代码似乎完全相同。我觉得这很违反直觉,这里发生了什么?感谢您的时间。
您提出了三种不同的场景:
await声明(注释掉两者)await task1(注释掉第二个)await task2(注释掉第一个)这是你的脚本;task2为了说明起见,稍微延长睡眠时间。
# tasktest.py
import time
import asyncio
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(3, 'world'))
print('started at', time.strftime('%X'))
await task1
# await task2
print('finished at', time.strftime('%X'))
asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)
await声明这是肉asyncio.run():
loop = events.new_event_loop()
try:
events.set_event_loop(loop)
loop.set_debug(debug)
return loop.run_until_complete(main) # < -----
finally:
try:
_cancel_all_tasks(loop) # < -----
loop.run_until_complete(loop.shutdown_asyncgens())
finally:
events.set_event_loop(None)
loop.close()
Run Code Online (Sandbox Code Playgroud)
重要的是,循环只关心main()是否完成,然后取消与正在运行的事件循环关联的所有其他任务。(每个任务在指定时都绑定到一个事件循环。)
如果main()不带任何await语句定义,则create_task()调度要执行的任务,但main()不等待其中任何一个完成。
await task1设置:
await task1
# await task2
Run Code Online (Sandbox Code Playgroud)
输出:
(base_py37) $ python3 tasktest.py
started at 11:06:46
hello
finished at 11:06:47
Run Code Online (Sandbox Code Playgroud)
这两个任务都从挂起状态变为运行状态,但只能task1完成,因为main()只等待一个耗时约 1 秒的任务,不足以task2运行。* (注意main()只需要 1 秒。)
await task2设置:
# await task1
await task2
Run Code Online (Sandbox Code Playgroud)
输出:
(base_py37) $ python3 tasktest.py
started at 11:08:37
hello
world
finished at 11:08:40
Run Code Online (Sandbox Code Playgroud)
这两个任务未决运行搬了,现在都task1和task2完整,由于main()对大约需要3秒,足够长的任务都完成运行任务等待。
*这至少适用于我的设置(Mac OSX,...),但正如这里的另一个答案中提到的,在另一个设置上的时间可能会有所不同,如果任务运行时间相似,两者都可能会运行在像案例#2 这样的地方。