协程 的概念
协程 是为非抢占式多任务产生子程序的计算机程序组件,协程允许不同入口点在不同位置暂停或开始执行程序。
基本上
async
和await
产生神奇的生成器,我们称之为协程,同时需要一些额外的支持例如awaitable
对象以及将普通生成器转化为协程。所有这些加到一起来支持并发,这样才使得 Python 更好地支持异步编程。
Python 3.5 中的 async/await =
Python 3.3 中的 yield from +
Python 3.4 中的 asyncio
Python 2.2 中的生成器让代码执行过程可以暂停。Python 2.5 中可以将值返回给暂停的生成器,这使得 Python 中协程的概念成为可能。
加上 Python 3.3 中的yield from
,使得重构生成器与将它们串联起来都很简单。
async 和 await 是如何运作的
# python 3.4
import asyncio
# asyncio.coroutine 修饰器用来标记作为协程的函数,asyncio 要求所有要用作协程的生成器必须由asyncio.coroutine修饰。
@asyncio.coroutine
def countdown(number, n):
while n > 0:
print('T-minus', n, '({})'.format(number))
#
yield from asyncio.sleep(1)
n -= 1
# 事件循环
loop = asyncio.get_event_loop()
tasks = [
asyncio.ensure_future(countdown("A", 2)),
asyncio.ensure_future(countdown("B", 3))]
# 监听,直到完成它需要做的一切
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
Python 3.5 添加了
types.coroutine
修饰器,也可以像asyncio.coroutine
一样将生成器标记为协程。你可以用async def
来定义一个协程函数,虽然这个函数不能包含任何形式的 yield 语句;只有 return 和await
可以从协程中返回值。
用
async def
可以定义得到 协程。定义协程的另一种方式是通过types.coroutine
修饰器 –从技术实现的角度来说就是添加了 CO_ITERABLE_COROUTINE标记– 或者是collections.abc.Coroutine
的子类。你只能通过基于生成器的定义来实现协程的暂停。