Python高级-异步编程

asyncio

Python 提供协程语义,通过 async def 声明协程,通过 await 关键字调用协程。

协程是异步io中的基本执行单元,基于生成器原理实现(yield, yield from),在执行过程中能将自身挂起出让CPU执行权,在未来又可以被唤醒。

事件循环(event-loop)则用来驱动多个协程并发执行,内部存在一个任务队列,用于存储待执行的协程列表。

asyncio 提供了事件循环的实现,是一个常用的异步编程框架,另外 curio 也提供了事件循环的实现。

future 概念表示一个异步任务的提交结果(注意是提交结果,不是执行结果),在任务被提交到事件循环后(放入任务队列中),则会返回一个 future 对象(或者是子类 task)。通过 future 对象可以获取异步任务的执行情况,以及执行结果。

另外 future 还提供了 add_done_callback 接口可以设置回调方法,在异步任务完成之后会执行所有的回调方法,在事件循环中通过这个方式将被挂起的协程重新唤醒。

操作系统io模型

特性select()poll()epoll() / kqueue()devpoll()
性能最差 (全量拷贝+全量遍历)较差 (全量拷贝+全量遍历)最佳 (只拷贝一次,只返回就绪)最佳
FD 限制1024/2048 (::FD_SETSIZE::)无固定限制 (受内存限制)无固定限制 (受内存限制)无固定限制 (受内存限制)
事件通知掩码位反填,需再次遍历检查结构体 revents 字段,需遍历检查仅返回就绪列表,基于事件驱动仅返回就绪列表
复杂度简单略复杂较复杂 (create, ctl, wait)较复杂 (文件操作)
跨平台性最佳 (通用)良好 (Unix-like)Linux / BSD 系列特有Solaris 特有
工作模式LTLTLT / ETLT

Epoll

文件描述符是进程访问文件(以及其他 I/O 资源)的抽象句柄,应用进程运行在用户态,无法直接操作系统文件,而是将文件描述符告知系统内核,由内核操作对应文件。