本文简介由 AI 生成。
记录两篇介绍 Linux 异步 IO 模型与事件循环的文章,一篇讲底层系统调用,一篇讲上层的事件循环实现,合在一起可以完整地理解从 select/poll/epoll 到 asyncio 的整条链路。
Julia Evans 的文章以服务端需要同时监听大量文件描述符为背景,介绍了 select、poll 与 epoll 三种方式:前两者每次调用都需要内核重新检查全部文件描述符,内核不会记住要监控的列表,因此连接数上来后性能下降;epoll 通过 epoll_create、epoll_ctl、epoll_wait 让内核记住并只返回真正有事件的描述符,还讨论了水平触发与边缘触发的区别,以及 Go、Node.js、nginx 等对 epoll 的使用。
Medium 上的另一篇文章则从 Linux 机制的角度剖析 Python asyncio 事件循环:事件循环底层通过 selectors 模块选择 EpollSelector,进而使用内核的 epoll 对象(进程里表现为 anon_inode:[eventpoll] 描述符);每次迭代计算超时后调用 epoll_wait 阻塞等待。定时器决定了 epoll_wait 的最大等待时长,而 self-pipe trick(一对 socketpair)用于在事件循环无限等待期间被其他线程或信号唤醒,三种机制的结果统一进入 _ready 队列顺序执行。
References
Async IO on Linux: select, poll, and epoll | Julia Evans
The Event Loop in asyncio: How Python Code Works on Top of Linux Mechanisms | Stanislav Garanzha