Python 的异步 I/O 是通过标准库 asyncio
及其生态构成的。
好的材料:
- FluentPythonCh18 是我入门
asyncio
的材料,但是里面的内容基于 Python 3.4,没有后来引入的async
/await
关键字,一些 API 也发生了变化;不过跟设计相关的内容仍值得看 - Python 的 官方文档 是不错的入门和使用材料
- Asyncio 的 单独文档,里面有更详细的例子和相对平缓的学习曲线
下面的内容基于 Python 3.7。这里给一个理解整个体系的索引,看完这个索引你应该能更好地理解 asyncio 的 API 设计。相应的 API、代码示例等,需要再通过 Python 官方文档、框架文档或者其他渠道去学习。
核心模型
asyncio
通过异步 I/O 来达到 CPU 的最大利用,从而提升 Python 服务的响应时间和吞吐率。它使用的方式是 event loop。event loop 一般有两种运作机制,一种是异步回调 callback,一种是协程。Python 在语言层面上支持了协程,又提供了 async
/ await
关键字来方便使用。
业务程序跟 event loop 交互,关心几个事情:
- 任务以怎样的形式表达?(awaitable)
- 如何将任务放进 event loop 并被调度?
- 如何获得任务的结果和异常?
调度的机制带来的问题:
- 如何同时运行多个任务?
- 如何终止一个运行中的任务?
- 如何给任务设置超时?
多任务协作带来的问题:
- 如何等待一个任务结束?
- 不同任务间的同步机制有什么?:Synchronization Primitives
- 不同任务间的数据传递机制?:Queens
异步 I/O API
因为 asyncio
模型上是异步的,因此 Python 标准库中原有的 blocking I/O 函数不能被使用。asyncio
必需将这些功能实现在自己 的生态中。
- 异步网络 I/O:
- High-level API:Steams
- Low-level API: Event loop, Transports and Protocols
- 异步文件操作:aiofile,由于操作系统没有成熟通用的异步 API,aiofile 通过线程来模拟
- 其他异步 I/O 库,参考 awesome-asyncio
Event loop? (Really?)
我对 event loop 的设计存疑。Event loop 的功能,事实上不像它的字面意思上一样,它不仅做事件驱动,还 兼顾 网络 I/O、TLS 升级、监听文件描述符、处理管道、信号、以及运行子进程。
与其他异步框架的对比和交互?
Logged into ClickUp tasks.
- Asyncio 对比 Twisted 和 Tornado?
- Asyncio 对比 gevent 和 eventlet?
- Twisted 有一个
asyncioreactor
,可以使用 asyncio 的 event loop 来驱动它的 Reactor;看看这两者是怎样整合的 - 看看 Twisted 作者的 The Report Of Our Death 一文
其他零碎的点
- 任务如何主动让出运行权?如何 sleep?:Waiting Primitives
- 如何在 asyncio 程序中运行同步(blocking)程序?:Running Blocking Code
- 如何提升程序的并发量?多线程的可能性:Concurrency and Multithreading
- 调试的技巧