多任务-协程异步模块asyncio 使用解读

"""
代码运行环境:
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}")


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值