"""
代码运行环境:
PyCharm 2019.3
Python3.8
版本说明 1 :
asyncio (自动切换阻塞) python3.4版本后加入
async & await关键字 python3.5版本后加入
参考文档: https://www.cnblogs.com/Young-shi/p/15442990.html
asyncio的原理 :
asyncio的原理就是通过把N个任务放到一个死循环中,
那么放入前我们需要先获得一个循环器的对象。然后在循环器中,N个任务组成任务列表,
每轮循环,循环器返回 可执行任务 和 已经完成任务,可执行任务丢到执行列表,准备执行;
已完成任务从任务列表中删除。最后任务列表为空的时候,那么循环结束。
方法说明:
ensure_future:
包装一个协程序或一个可等待对象(协程对象,Future,Task对象)。如果该参数是一个Future,则会直接返回它
await 关键字说明:
await + 可等待对象(协程对象,Future,Task对象) <io等待>, 一个协程函数里可以有多个await
协程函数体中,遇到await,函数是等待的,不会切换运行内部的其他函数.这种运行方式和普通的函数从上而下执行顺序没有区别
"""
import asyncio
import time
# 定义协程函数
async def func(task_no, delay_time):
print(f"任务{task_no} start; 将休眠{delay_time}秒")
# await + 可等待对象(协程对象,Future,Task对象);
await asyncio.sleep(delay_time)
print(f"任务{task_no} end!!")
return f"这里是{task_no}的返回值"
# 【debug】调用协程函数,函数内部代码不会执行,只是会返回一个协程对象(这里obj就是协程对象)。
cor_obj = func("t1", 1)
print(f"协程对象:{cor_obj};\n协程对象类型: {type(cor_obj)}")
async def main():
print("----- main 开始执行 -----")
# 在事件循环器中添加多个任务
task1 = loop.create_task(func("task1", 1))
task2 = loop.create_task(func("task2", 2))
# 生成任务task3、task4 Future,Task对象 关系是什么?
task3 = asyncio.ensure_future(func("task3", 3))
# python 3.7以上版本适用
task4 = asyncio.create_task(func("task4", 10))
print(f"任务1的对象:{task1};\n任务1的类型: {type(task1)}")
print(f"任务3的对象:{task3};\n任务3的类型: {type(task3)}")
print(f"任务4的对象:{task4};\n任务4的类型: {type(task4)}")
print(f"【Future,Task对象 关系】查看创建实例task4 类的父类为: {task4.__class__.__base__}")
ret1 = await task1
ret2 = await task2
ret3 = await task3
ret4 = await task4
print(f"执行await task1/task2/task3 的返回值: \n{ret1} - {ret2} - {ret3} - {ret4}")
print("----- main 结束执行 -----")
start_time = time.time()
# ---------运行任务列表 方式一-----------
# 获取一个事件循环器的对象
loop = asyncio.get_event_loop()
# 将任务放到任务列表中 run_until_complete 只接收一个future对象
# 这里传给它的却是协程对象main(),之所以能这样,是因为它在内部做了检查,通过 ensure_future 函数把协程对象包装(wrap)成了 future
loop.run_until_complete(main())
# 我们也可以调用asyncio.wait()协程函数, 将多个协程函数包装(wrap)成 future,再添加到任务列表(本质上asyncio.wait内部也是调用ensure_future)
# tasks = asyncio.wait([
# func("task5", 5),
# func("task6", 10),
# ])
# loop.run_until_complete(tasks)
# ---------运行任务列表 方式二-----------
# python3.7对循环器又进行了封装,只需要调用run方法即可
# 获取循环器对象和添加任务列表一步完成
# asyncio.run(func("test", 5))
end_time = time.time()
print(f"程序执行时间{end_time - start_time}")
多任务-协程异步模块asyncio 使用解读
最新推荐文章于 2024-03-19 15:00:00 发布