news 2026/4/29 4:14:06

【网络】【Linux】多路转接技术

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【网络】【Linux】多路转接技术

Linux 中的多路转接技术(IO 多路复用 / I/O Multiplexing)是高并发网络服务器最核心的技术手段之一。

它解决的核心问题:一个线程/进程如何高效地同时“监视”大量 socket(文件描述符),在其中任意一个或多个“就绪”(可读、可写、异常)时才去处理,而不是每个 socket 都单独开线程或反复轮询。

Linux 目前主流提供了三种实现方式:select → poll → epoll(从老到新、从差到好)。

一、核心概念对比表(2025-2026 视角)

特性selectpollepoll (主流)
系统调用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. select(最古老、最简单)

工作流程

  1. 用户把关心的 fd 集合放入三个 fd_set(读、写、异常)
  2. 调用 select(nfds, &rfds, &wfds, &efds, &timeout)
  3. 内核遍历所有 fd,检查是否就绪 → 修改 fd_set 位图
  4. 返回就绪个数,用户自己遍历 fd_set 找哪些位置为1

致命缺点

  • 每次调用都要把整个 fd 集合从用户态 → 内核态拷贝(O(n))
  • 内核每次都要线性扫描整个集合(O(n))
  • fd 上限 1024(位图大小固定,可改但不推荐)
  • 返回后用户还需再次遍历找就绪 fd(O(n))
2. poll(select 的改进版)

改进点

  • 用 pollfd 数组代替 fd_set:{fd, events, revents}
  • 没有 1024 限制(只受内存限制)
  • 事件和结果分离(events 传入,revents 返回)

仍存在的缺点

  • 每次调用仍需把整个 pollfd 数组拷贝到内核(O(n))
  • 内核仍需遍历整个数组检查(O(n))
  • 返回后用户仍需遍历数组找 revents != 0 的 fd(O(n))
3. epoll(目前 Linux 高并发的事实标准)

革命性设计事件驱动 + 内核维护就绪链表

三大核心函数

// 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 和事件

关键优势

  • 红黑树存储所有监控 fd(增删改 O(log n))
  • 内核回调机制:当 fd 就绪时,内核主动把事件加入就绪链表(callback 机制)
  • epoll_wait 只返回就绪的 fd(O(1) 均摊获取就绪数)
  • 支持边缘触发(ET)vs水平触发(LT)
    • LT(默认):只要缓冲区有数据就一直通知(类似 select/poll)
    • ET:只在状态变化时通知一次(高性能,但需一次性读完)

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;// 错误处理}// 处理数据}}}}

三、实际选型建议(2025-2026)

场景推荐选择理由简述
连接数 < 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 的,都可以直接告诉我,我再给你展开更具体的代码和分析。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 6:41:24

学长亲荐2026TOP10AI论文软件:MBA毕业论文写作全测评

学长亲荐2026TOP10AI论文软件&#xff1a;MBA毕业论文写作全测评 2026年MBA论文写作工具测评&#xff1a;为何需要一份权威榜单&#xff1f; 在MBA学习过程中&#xff0c;撰写高质量的毕业论文不仅是学术能力的体现&#xff0c;更是对未来职业发展的重要铺垫。然而&#xff0…

作者头像 李华
网站建设 2026/4/26 11:16:42

智慧医院移动服务平台源码|含管理端+用户端|成熟商用解决方案

掌上医院预约挂号管理系统源码&#xff0c;智慧医院源码掌上医院预约挂号管理系统是一套集后台管理端与用户使用端于一体的综合性医疗服务平台。用户可通过微信公众号与支付宝小程序便捷访问。系统基于C#/.NET uni-app SQL Server 2012技术栈开发&#xff0c;采用Visual Stud…

作者头像 李华
网站建设 2026/4/24 18:06:49

02.Win11 系统 Python 编程环境搭建实操指南(新手友好)

目录前言一、准备工作二、下载 Python 安装包2.1 访问 Python 官方网站2.2 版本选择逻辑2.3 下载对应安装包三、安装 Python&#xff08;关键步骤&#xff0c;必看&#xff01;&#xff09;3.1 核心选项勾选&#xff08;重中之重&#xff09;3.2 安装模式选择3.3 自定义组件配置…

作者头像 李华
网站建设 2026/4/28 7:18:16

logging模块,scrapy全站爬取

1.longging模块 logging是python内置的日志处理模块 在scrapy中,可以配置LOG_LEVEL来设置输出的日志等级,也可以在scrapy/settin/default_setting.py 路径下查看日志相关默认参数(需要修改的参数可以直接在settings.py文件中修改) #添加日志 LOG_LEVEL="WAREING"…

作者头像 李华
网站建设 2026/4/27 5:59:08

权利的本质是插队?县城婆罗门的毛细血管,我们该走还是留?

权利的本质是插队&#xff1f;县城婆罗门的毛细血管&#xff0c;我们该走还是留&#xff1f; 目录 权利的本质是插队&#xff1f;县城婆罗门的毛细血管&#xff0c;我们该走还是留&#xff1f;不是宗教意义上的阶层&#xff0c;而是基层独有的生态于是很多人心里都冒出来一个天…

作者头像 李华