Python开发者实战指南:Doris部署、连接与Superset可视化集成
2026/7/5 12:17:38
Linux 中的多路转接技术(IO 多路复用 / I/O Multiplexing)是高并发网络服务器最核心的技术手段之一。
它解决的核心问题:一个线程/进程如何高效地同时“监视”大量 socket(文件描述符),在其中任意一个或多个“就绪”(可读、可写、异常)时才去处理,而不是每个 socket 都单独开线程或反复轮询。
Linux 目前主流提供了三种实现方式:select → poll → epoll(从老到新、从差到好)。
| 特性 | select | poll | epoll (主流) |
|---|---|---|---|
| 系统调用 | select() | poll() | epoll_create1() + epoll_ctl() + epoll_wait() |
| 最大文件描述符数量 | 通常 1024(FD_SETSIZE) | 无硬限(取决于内存) | 无硬限(通常几十万) |
| 内核-用户态拷贝开销 | 每次调用拷贝整个 fd_set(O(n)) | 每次拷贝整个 pollfd 数组(O(n)) | 只拷贝就绪事件(O(1) 均摊) |
| 就绪事件返回方式 | 修改传入的 fd_set | 修改 pollfd.revents | 返回独立的事件链表(epoll_event 数组) |
| 是否支持边缘触发 | 水平触发(LT) | 水平触发(LT) | 支持 LT / ET(边缘触发) |
| 是否支持 O(1) 获取就绪数 | 否(需遍历位图) | 否(需遍历数组) | 是(只返回就绪个数) |
| 性能(1w 连接,100 活跃) | ★☆☆☆☆ | ★★☆☆☆ | ★★★★★ |
| 跨平台性 | 极好(POSIX) | 好(POSIX) | 仅 Linux |
| 当前主流使用场景 | 遗留系统、小型服务 | 中型服务、跨平台需求 | Nginx、Redis、libevent、Go runtime 等 |
| 引入内核版本 | 很早 | 较早 | Linux 2.5.44(2002) |
工作流程:
致命缺点:
改进点:
仍存在的缺点:
革命性设计:事件驱动 + 内核维护就绪链表
三大核心函数:
// 1. 创建 epoll 实例(红黑树 + 就绪链表)intepoll_fd=epoll_create1(0);// 或 epoll_create(size) 已废弃// 2. 注册/修改/删除 监控的 fd 和事件intepoll_ctl(epoll_fd,EPOLL_CTL_ADD/DEL/MOD,fd,&event);// event 示例structepoll_eventev;ev.events=EPOLLIN|EPOLLET;// 可读 + 边缘触发ev.data.fd=client_fd;// 或 ev.data.ptr = 自定义结构体epoll_ctl(epoll_fd,EPOLL_CTL_ADD,client_fd,&ev);// 3. 等待就绪事件(阻塞或超时)intn=epoll_wait(epoll_fd,events,maxevents,timeout);// events 数组中就是已经就绪的 fd 和事件关键优势:
ET 模式经典写法(非阻塞 + 循环读写):
while(1){intn=epoll_wait(epfd,events,MAX_EVENTS,-1);for(inti=0;i<n;i++){intfd=events[i].data.fd;if(events[i].events&EPOLLIN){charbuf[1024];while(1){// 必须循环读到 EAGAINintlen=read(fd,buf,sizeof(buf));if(len<=0){if(errno==EAGAIN||errno==EWOULDBLOCK)break;// 错误处理}// 处理数据}}}}| 场景 | 推荐选择 | 理由简述 |
|---|---|---|
| 连接数 < 1000,活跃连接少 | select / poll | 实现最简单,跨平台 |
| 跨平台需求(Linux + BSD + Windows) | poll | 比 select 更灵活,无 1024 限制 |
| 高并发服务器(1w+ 连接) | epoll | 性能碾压,Nginx/Redis 标配 |
| 需要边缘触发 + 极致性能 | epoll ET | 减少唤醒次数,但代码复杂度高 |
| 想跨平台又要高性能 | libevent / libev / io_uring | 封装了 epoll/kqueue 等 |
一句话总结:
select 和 poll 已经过时,除非你有跨平台强需求,否则现代 Linux 高并发网络服务一律首选 epoll。
如果你想看 epoll 的完整服务器示例代码(C语言)、与 io_uring 的对比、ET vs LT 的详细实验、或者 Nginx 是如何用 epoll 的,都可以直接告诉我,我再给你展开更具体的代码和分析。