本文首发于:行者AI
在近期的编码工作过程中遇到了async和await装饰的函数,查询资料后了解到这种函数是基于协程的异步函数。这类编程方式称为异步编程,常用在IO较频繁的系统中,如:Tornado web框架、文件下载、网络爬虫等应用。协程能够在IO等待时间就去切换执行其他任务,当IO操作结束后再自动回调,那么就会大大节省资源并提供性能。接下来便简单的讲解一下异步编程相关概念以及案例演示。
1. 协程简介
1.1 协程的含义及实现方法
协程(Coroutine),也可以被称为微线程,是一种用户态内的上下文切换技术。简而言之,其实就是通过一个线程实现代码块相互切换执行。例如:
def func1():
print(1)
... # 协程介入
print(2)
def func2():
print(3)
... # 协程介入
print(4)
func1()
func2()
上述代码是普通的函数定义和执行,按流程分别执行两个函数中的代码,并先后会输出:1、2、3、4
。但如果介入协程技术那么就可以实现函数见代码切换执行,最终输入:1、3、2、4
。
在Python中有多种方式可以实现协程,例如:
-
greenlet,是一个第三方模块,用于实现协程代码(Gevent协程就是基于greenlet实现);
-
yield,生成器,借助生成器的特点也可以实现协程代码;
-
asyncio,在Python3.4中引入的模块用于编写协程代码;
-
async & awiat,在Python3.5中引入的两个关键字,结合asyncio模块可以更方便的编写协程代码。
前两种实现方式较为老旧,所以重点关注后面的方式
标准库实现方法
asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。
import asyncio
@asyncio.coroutine
def func1():
print(1)
yield from asyncio.sleep(2) # 遇到IO耗时操作,自动化切换到tasks中的其他任务
print(2)
@asyncio.coroutine
def func2():
print(3)
yield from asyncio.sleep(2) # 遇到IO耗时操作,自动化切换到tasks中的其他任务
print(4)
tasks = [
asyncio.ensure_future( func1() ),
asyncio.ensure_future( func2() )
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
关键字实现方法
async & await
关键字在Python3.5版本中正式引入,代替了 装饰器,基于他编写的协程代码其实就是上一示例的加强版,让代码可以更加简便可读。
import asyncio
async def func1():
print(1)
await asyncio.sleep(2) # 耗时操作
print(2