在python2.x和python3.x早期版本的时候,协程的主流实现方法是gevent,这个我之前讲过
asyncio在python3.4后内置在python中了,在后面还有async/await,更后面有aiohttp,flask实现就有参照aiohttp
async和await分别又来替换早期协程的asyncio.coroutine和yield from。
从此以后,协程就是python中一个新的语法,而不是与生成器混为一谈了
事件循环和协程的引入,可以极大提高高负载下程序的IO能力
async with(异步上下文管理)
async for(异步迭代器)
这里要讲的asyncio的编程模型其实就是消息循环,把会阻塞的任务放进EventLoop中,程序继续往下走,等到任务中有执行好的,就切回去继续执行下一步,有点类似与select,但是select是轮询文件描述符
异步在遇到阻塞的情况下,不会停下来等待,而是直接去处理其他的任务,通过状态,信号,回调来通知调用者处理结果。
异步编程可以说是没有回头路的编程,既然开始了,那就要异步到底
同步和异步的代码
同步:
import time
def hello():
time.sleep(1)
def run():
for i in range(5):
hello()
print('Hello World:{}'.format(time.time()))
run()
改造成异步:结果是,五个任务以下全部都卡在了yield from asyncio.sleep(1),然后等 <1秒的时间才进行打印(大家这里要好好理解异步的工作流程)
import time
import asyncio
# 定义异步函数,加一个装饰器,使之变成协程
@asyncio.coroutine
def hello():
'''
yield from语法可以让我们方便地调用另一个generator。由于asyncio.sleep()也是一个coroutine,所以线程不会等待asyncio.sleep(),而是直接中断并执行下一个消息循环。
当asyncio.sleep()返回时,线程就可以从yield from拿到返回值(此处是None),然后接着执行下一行语句。
把asyncio.sleep(1)看成是一个耗时1秒的IO操作,在此期间,主线程并未等待,而是去执行EventLoop中其他可以执行的coroutine了,因此可以实现并发执行
'''
# 这里不会停住,而是将任务中再拿出一个来执行
r = yield from asyncio