news 2026/4/20 14:34:53

【网络】【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/17 20:34:26

Vue2 的数据响应式原理给实例新增响应式属性

Vue2 响应式原理的案例 <template><div id"app"><div>用户名&#xff1a;{{ user.name }}</div><div>年龄&#xff1a;{{ user.age }}</div> <button click"addAgeDirectly">直接添加年龄&#xff08;无响应式&…

作者头像 李华
网站建设 2026/4/18 10:12:07

轰炸敌人,最多可以摧毁的敌人城堡数目

我的解法&#xff1a; 对于每一个空位置&#xff0c;进行一次bfs&#xff0c;从上下左右四个方向去寻找&#xff0c;这是岛屿问题的相似处理&#xff0c;但是这个题可以优化&#xff0c;因为横竖方向可以进行动规优化。 我们不需要对每个 0 都重新数一遍它所在的行和列有多少敌…

作者头像 李华
网站建设 2026/4/18 10:45:40

微信小程序 == rsa加解密工具

wxmp-rsa 1、简介 前端rsa加解密工具。 基于jsencrypt修改扩展功能。兼容小程序环境&#xff0c;压缩后60kb左右的大小&#xff0c;节省小程序空间。支持超长文本加解密。支持中文字符的加解密。 仓库地址 https://github.com/jiayc4215/wxmp-rsa2、安装 npm i wxmp-rsa …

作者头像 李华
网站建设 2026/4/17 23:16:37

安达发|精准排产,守护生命:医疗器械行业车间排产的数字化革命

在关乎人类生命健康的医疗器械制造领域&#xff0c;每一台设备、每一个部件的准时交付&#xff0c;都可能直接影响到患者的治疗与康复。这个行业以其严苛的质量法规&#xff08;如FDA、ISO 13485&#xff09;、复杂的生产工艺和极高的可追溯性要求而著称。在这样的背景下&#…

作者头像 李华
网站建设 2026/4/18 0:40:46

Spring MVC核心流程深度解析:从请求到响应的完美掌控

Spring MVC 核心流程深度解析&#xff1a;从请求到响应的完美掌控 Spring MVC 是 Spring 框架中处理 Web 请求的核心模块&#xff0c;基于 Model-View-Controller (MVC) 设计模式。它以 DispatcherServlet 为入口&#xff0c;实现从 HTTP 请求到响应的完整生命周期管理。下面从…

作者头像 李华
网站建设 2026/4/18 9:12:51

Java毕设选题推荐:基于springboot的游戏售卖商城系统基于SpringBoot+Vue的游戏装备交易商城系统【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华