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 特有 |
工作模式 | LT | LT | LT / ET | LT |
Epoll
文件描述符是进程访问文件(以及其他 I/O 资源)的抽象句柄,应用进程运行在用户态,无法直接操作系统文件,而是将文件描述符告知系统内核,由内核操作对应文件。