异步编程下await的理解
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 timeasync 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())