协程系列之asyncio与async/wait

395 阅读2分钟

1 asyncio

asyncio是标准库,内置了对异步IO的支持。它的编程模型就是一个消息循环,比如从asyncio模块中获取一个EventLoop的引用,然后把需要支持的协程放到EventLoop中执行。这样就实现了异步IO

import asyncio
​
​
@asyncio.coroutine
def say_hello():
    print('Hello Python!')
    # 调用asyncio.sleep(1), 设置延时
    # yield from是协程切换执行的函数
    yield from asyncio.sleep(1)
    print('Hello Django!')
​
​
# 创建EventLoop对象
loop = asyncio.get_event_loop()
# 执行异步函数say_hello
loop.run_until_complete(say_hello())
# 执行多个异步函数
loop.run_until_complete(asyncio.wait([say_hello(), say_hello()]))
loop.close()

result:

Hello Python!
Hello Django!
Hello Python!
Hello Python!
Hello Django!
Hello Django!

过程分析如下:

(1)使用@asyncio.coroutine作为函数的装饰器,使函数变为异步函数。

(2)调用get_event_loop()方法创建EventLoop对象

(3)由EventLoop对象调用run_until_complete()方法执行异步函数say_hello()

(4)如果需要同时执行多个异步函数,那么将多个函数以列表的形式表示,并作为asyncio.wait()方法的参数,由run_until_complete()方法执行。

(5)由EventLoop对象调用close()方法销毁EventLoop对象

2 async/wait

从3.5版本开始,引入了async/wait语句。其语法如下:

(1)将@asyncio.coroutine替换为async

(2)将ield from替换为await

import asyncio
import time
​
​
async def get_times():
    for i in range(2):
        print('进入等待')
        await asyncio.sleep(1)
        print('Hello times is', i)
​
​
async def say_hello():
    print('Hello Python!')
    # 调用asyncio.sleep(1), 设置延时
    await get_times()
    print('Hello Django!')
​
​
start_time = time.time()
# 创建EventLoop对象
loop = asyncio.get_event_loop()
# 执行异步函数say_hello
loop.run_until_complete(say_hello())
# 执行多个异步函数
loop.run_until_complete(asyncio.wait([say_hello(), say_hello()]))
loop.close()
end_time = time.time()
print('一共耗时:', end_time - start_time)

result:

Hello Python!
进入等待
Hello times is 0
进入等待
Hello times is 1
Hello Django!
Hello Python!
进入等待
Hello Python!
进入等待
Hello times is 0
进入等待
Hello times is 0
进入等待
Hello times is 1
Hello Django!
Hello times is 1
Hello Django!
一共耗时: 4.041677474975586

过程分析如下:

(1)将原有的@asyncio.coroutine和yield from分别改为async和await,并且还定义了异步函数get_times()

(2) 在异步函数say_hello()中,使用关键字await调用异步函数get_times()

(3)程序在执行异步函数get_times()的时候,当出现延时asyncio.sleep(1)时,程序自动切换并执行另一个异步任务