await理解
【asyncio.create_task】的作用:
不仅仅是创建一个任务,它还会立即将这个任务提交到事件循环中并开始执行。
这意味着即使你还没有使用 await 来等待这个任务完成,它也会在后台开始运行。
【关键点】
创建并立即执行:当你调用 asyncio.create_task(some_coroutine()) 时,事件循环会立即开始执行这个协程(coroutine)。
【await】的作用:
await 的作用是暂停上层任务的执行,直到被 await 的子任务完成并返回结果。它并不会影响子任务本身的并发执行,而是让事件循环有机会去处理其他任务。
- await coroutine对象【
串行
】 - await task
- 【
串行
】每写一个task就await一下,再写下一个task2,再await task2… - 【
并行
】把所有的task都写完,再集中写所有的await… 这种存在线程安全问题,具体看:并发异步编程之争:协程(asyncio)到底需不需要加锁?
- 【
import asyncio
import time
async def task_b(delay):
print(f"Entry Task B......")
await asyncio.sleep(delay)
print(f"Task B woke up")
return "Result of task B"
async def task_c(delay, dependency_result):
print(f"Task C is using the result of the dependency: {dependency_result}")
await asyncio.sleep(delay)
print(f"Task C woke up")
async def main():
# ************* 1、直接await coroutine **************
'''
当await coroutine对象时:不会创建task,await被顺序执行,所以总体返回时长为3+5=8s
'''
print(f"started at {time.strftime('%X')}")
ret1 = await task_b(3)
print(type(ret1))
await task_c(5, ret1)
# await task_c(5, "哈哈哈")
print(f"finished at {time.strftime('%X')}")
# ************* 2、创建task后就await, 再创建下一个task **************
'''
当await task_b_future 代码写在task_c_future创建之前时, await是顺序执行:总体返回时长受所有task的等待时长总和限制,即3+5=8s
'''
# task_b_future = asyncio.create_task(task_b(3))
# print(f"started at {time.strftime('%X')}")
# # result_b = await task_b_future
# await task_b_future
# task_c_future = asyncio.create_task(task_c(5, "哈哈哈"))
# await task_c_future
# print(f"finished at {time.strftime('%X')}")
# ************* 3、先创建所有的task,再集中await **************
'''
当await task_b_future 代码写在task_c_future创建之后时:总体返回时长仅受最大等待时间限制,即5s
这是因为task_b_future、task_c_future几乎是同时创建的,而create_task的功能不仅是“创建”,还有“立即执行”,
所以即使不执行await task_b_future、await task_c_future,task_b、task_c的方法体已经在跑了,
只是加上await后会告诉上层main任务,你最后的print(f"finished at {time.strftime('%X')}")必须要等我这两个任务完成才可以执行,如果不加,会立即执行print!
'''
# task_b_future = asyncio.create_task(task_b(3)) # 创建并立即开始执行 task_b。
# print(f"started at {time.strftime('%X')}")
# task_c_future = asyncio.create_task(task_c(5, "哈哈哈")) # 创建并立即开始执行 task_c。
# await task_b_future # 暂停 main 任务(上层任务)的执行,直到 task_b (子任务)完成。
# await task_c_future # 暂停 main 任务(上层任务)的执行,直到 task_c (子任务)完成。
# print(f"finished at {time.strftime('%X')}")
# 运行事件循环
'''
1、run会把异步方法(coroutine方法)main()变成一个task,并交给event_loop。
2、event_loop的最小执行单位是task。
'''
asyncio.run(main())