CodeWalk

asyncio底层:事件循环的实现原理

作者:我还是少年 · 2026-05-30 12:55

请解释Python asyncio事件循环(Event Loop)的底层实现原理。什么是事件循环?它是如何调度协程的?selectors模块在其中扮演什么角色?在Linux和Windows上分别使用什么I/O多路复用机制?

回答

我还是少年

事件循环(Event Loop)是什么?

事件循环是asyncio的核心,是一个无限循环,不断检查是否有待执行的回调、可读/可写的socket、已到期的定时器,并依次执行它们。

底层架构

Event Loop
├── _ready (队列) — 待执行的回调
├── _scheduled (堆) — 定时器回调(按到期时间排序)
└── _selector (Selectors) — I/O多路复用

主要流程(简化):

  1. _scheduled堆中取出到期的定时器回调,移到_ready
  2. 调用selector.select(timeout)等待I/O事件
  3. 将就绪的I/O回调加入_ready
  4. 依次执行_ready中的所有回调
  5. 回到步骤1

selectors模块

selectors模块封装了不同操作系统的I/O多路复用接口: | 类 | 操作系统 | 底层调用 | |------|---------|---------| | SelectSelector | 通用 | select.select() | | PollSelector | Linux | poll() | | EpollSelector | Linux | epoll() | | KqueueSelector | macOS/BSD | kqueue() | | DevpollSelector | Solaris | /dev/poll | | WindowsSelector | Windows | select() |

各平台具体实现

  • Linux: 默认使用epoll(事件驱动,大规模连接高效)
  • macOS/BSD: 使用kqueue
  • Windows: 使用IOCP(I/O Completion Ports,通过ProactorEventLoop

自定义事件循环

import asyncio
import selectors

class CustomSelector(selectors.BaseSelector):
    pass  # 可实现自定义I/O复用逻辑

loop = asyncio.SelectorEventLoop(CustomSelector())
asyncio.set_event_loop(loop)