Python3异步IO编程中协程的介绍和使用

因为Python有GIL全局线程锁,所以在Python中对于IO密集型任务可采用多并发的异步实现方式。Python 3 中的协程是异步编程的一种形式,它允许在代码中创建可暂停的函数,以便其他任务可以运行,而不会阻塞程序的执行。关键字async和await 是 Python 3.5 之后引入的语法,用于编写协程。

async def 用于定义协程函数;await可以获取到可等待对象的返回值,当事件循环遇到await后会调度其他任务。

可等待对象包括:

  1. 协程对象:协程函数生成的对象;
  2. Task对象:通过asyncio.create_task(coroutine)(3.7开始有)创建,用于将任务添加到事件轮询(循环)中。
  3. Future对象。

在Python 3.7以前,使用协程的方式如下:

import asyncio

# 定义协程函数
async def work_proc(n):
    for i in range(5):
        print(f"我是协程任务{n},运行到第{i}步.")
        await asyncio.sleep(1)  # sleep参数单位为秒

work_obj = work_proc(1)  # 得到协程对象,此时没有调度执行。协程函数不能直接调用

# 将协程函数转为协程对象,并放到列表中
tasks = [work_proc(1), work_proc(2)]
# 使用asyncio创建事件循环对象,用于并发调度多个协程任务
loop = asyncio.get_event_loop()
# 使用事件循环对象调度多个协程任务,列表中的多个协程任务并发异步执行
loop.run_until_complete(tasks)

Python 3.7及以上版本使用协程的方法:

import asyncio

# 定义协程函数
async def work_ret(n):
    print(f"我是协程任务{n},开始执行...")
    await asyncio.sleep(n)
    print(f"我是协程任务{n},执行完毕.")
    return f"这是我的{n}协程任务"

# 协程异步主函数
async def main_async():
    print('协程任务准备调度...')
    task1 = asyncio.create_task(work_ret(5))
    task2 = asyncio.create_task(work_ret(2))

    # 任务单独提交方式
    res1 = await task1  # 继续调用后面的await代码
    print('协程任务1已经提交执行...')  # 此句会被阻塞,等待上句执行完毕立即执行,不受下个await影响
    res2 = await task2  # 不受上一个await阻塞,上一个await提交后,立即提交该任务
    print('协程任务2已经提交执行...')  # 此句会被阻塞,等待上面2个await执行完毕执行
    print(f"协程任务{1}完成,返回结果{res1}")
    print(f"协程任务{2}完成,返回结果{res2}")

asyncio.run(main_async())

多任务并发的情况下,可采用创建任务循环列表的使用如下:

async def main_async():
    tasks = [asyncio.create_task(work_ret(n)) for n in range(9)]
    # 1.wait方式并发调度,获取到的返回值是乱序的
    done, pending = await asyncio.wait(tasks)  # tasks列表中所有任务并发,此处阻塞,done为任务的返回值,pending为状态
    for item in done:
        res = item.result()  # res为每个任务的返回值
        print(res)
    # 2.gather方式并发调度,可收集所有任务的返回值,且返回值是有顺序的,对应任务列表的顺序
    res = await asyncio.gather(*tasks)  # tasks列表中所有任务并发,此处阻塞,res为返回结果组成的列表
    print(res)

asyncio.run(main_async())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值