当前位置: 首页 > news >正文

Go 的 IO 多路复用

Go 的 IO 多路复用epoll vs select 差异,以及 Go runtime 中是如何使用它们的。


✅ 一、什么是 IO 多路复用?

IO 多路复用解决的问题是:

一个线程同时监听多个文件描述符(socket 等)的 IO 状态变化
不需要为每个连接创建一个线程或阻塞在一个 IO 上

常见系统调用:

  • select
  • poll
  • epoll(Linux)
  • kqueue(BSD / macOS)
  • IOCP(Windows)

✅ 二、select vs epoll 区别(重点)

对比项selectepoll
支持的 fd 数量有上限,一般1024理论无限(由系统内存决定)
时间复杂度O(n) 每次扫描全部 fdO(1) 回调通知,只处理活跃 fd
内核与用户态交互每次都复制整个 fd 集合使用内核维护红黑树和就绪链表,无需重复传输大量数据
触发模式只支持 水平触发支持 水平触发 + 边缘触发(更高效)
资源消耗大,重复构造 fd 集合小,只在 add/del 时修改
大并发性能优秀,适合 10w+ 连接

一句总结:

select:每次全部扫描
epoll:事件通知,只处理变化的 FD
⇒ 大并发下 epoll 优势极大


✅ 三、为什么 Go 用 epoll(Linux)?

Go 的网络模型是 goroutine + epoll/kqueue + 协程调度器

用户写代码:阻塞 I/O
↓
Go runtime:用 epoll/kqueue 监控 socket
↓
有事件就唤醒对应的 goroutine

实际上,netpoller 负责底层事件循环:

平台多路复用机制
Linuxepoll
macOS / FreeBSDkqueue
WindowsIOCP

你写的看似阻塞的 conn.Read() 实际是:

  • goroutine 被 park(挂起)
  • IO 可读时,epoll 通知 runtime
  • runtime 唤醒该 goroutine

Goroutine ≠系统线程
一个线程同时调度成千上万 goroutines

✅ 所以 Go 在高并发网络服务中天生强大。


✅ 四、代码层使用体验

你写的代码不需要关心 epoll:

for {n, err := conn.Read(buf)if err != nil {return}fmt.Printf("read %d bytes\n", n)
}

Go runtime 自动协程化。


✅ 五、什么时候 select 仍会被使用?

  • 小规模 fd 管理,简单快速
  • 跨平台兼容
  • Go 内部在 netpoll 未启用场景下 fallback

✅ 六、一句话总结

select 采用轮询,fd 数量有限且 O(n) 性能差;
epoll 采用事件回调,仅返回活跃 fd,支持更大并发;
Go 的 Runtime 在 Linux 上使用 epoll 实现 IO 多路复用,协程调度隐藏了异步 IO 的复杂性,使阻塞 API 实际是高效的事件驱动模型。

实际编码中为什么感受不到?

理解 Go 网络模型的核心

Go 代码里看不到 select / epoll,但它们的特征仍然“渗透”在你的代码行为里。

我们从 开发者视角底层表现 两个层面看。


✅ 一、Go 层看不到 epoll/select,但它们在底层驱动

代码可能长这样:

for {conn, err := listener.Accept()if err != nil {continue}go handle(conn)
}func handle(conn net.Conn) {buf := make([]byte, 1024)for {n, err := conn.Read(buf)if err != nil {return}conn.Write(buf[:n])}
}

看起来是同步阻塞式写法:

  • Accept() 阻塞
  • Read() 阻塞
  • Write() 阻塞

👉 但在 Go runtime 底层

  • 每个 goroutine 被 runtime 管理;
  • netpoll 使用 epoll(Linux) / kqueue(macOS) / IOCP(Windows)
  • 当 IO 不可读/写时,goroutine 被“挂起”(park);
  • 事件到达后,runtime 唤醒对应 goroutine。

所以:

阻塞 API,非阻塞执行。

这就是 Go 的“同步写法 + 异步模型”特征。

http://www.dtcms.com/a/549496.html

相关文章:

  • 【论文精读】MicroCinema:基于分治策略的文本到视频生成新框架
  • 建设银行租房网站郑州网站建设包括哪些
  • Flink keyby使用随机数踩坑记
  • 行业网站建设方案室内设计师联盟首页
  • JAVA中的堆和栈
  • A2A协议的多智能体投顾引擎架构, 智能体生成年化418%,回撤11%,夏普比5.19的规则策略,附python代码
  • 建设黑彩网站需要什么药理学网站建设方案
  • Linux本机ping虚机ip Network unreachable
  • 个体工商户可以备案哪些网站做一个同城便民信息网站怎么做
  • 队列——速成
  • 南京建设网站的公司网易企业邮箱登录入口手机
  • R语言基于Rselenium模拟浏览器抓取DatabaseCommons数据-连载NO.04
  • 对于一些MP4文件的压缩
  • 基于Selenium和AI的图像处理
  • Selenium Wire 网络拦截实现方案
  • 无锡手机网站制作费用网页设计与网站建设在线考试
  • 【Qt】【1. 版本特性介绍】
  • pyside6的历史发展、Qt 介绍、PyQt 和 pyside6对比
  • 做没用的网站建立个网站
  • numpy的random函数总结
  • ⸢ 拾-Ⅱ⸥⤳ 威胁感知与响应建设方案:威胁运营威胁响应
  • Auto Dark Mode,一款Windows 自动深浅色切换工具
  • 惠民县建设网站信宜网站设计公司
  • 论文对应项目复现教程
  • 第165期 无需提示词的微调:Bonepoke 与系统姿态的隐藏调控旋钮
  • 口腔种植中叠腮技术的适应证与考量
  • 原码、反码、补码与正数、负数的运算关系介绍
  • ShimetaPi丨事件相机新版SDK发布:支持Python调用,可降低使用门槛
  • 计算机图形学:【Games101】学习笔记03——光栅化(三角形的离散化、深度测试与抗锯齿)
  • 如何掌握【Java】 IO/NIO设计模式?工厂/适配器/装饰器/观察者模式全解析