select、poll、epoll

在传入的性能差异是不是体现在,当有新的连接过来,此时需要将新的fd传入到内核中,但是poll/select需要出入整个数组,而epoll方式只需要出入单个fd?

1. select/poll 的情况

  • 它们没有内核中“长期保存的集合”

  • 每次调用 select()poll(),你都要把 整个数组/集合(所有要监控的 fd)重新传给内核。

  • 不管你只是新增了 1 个连接,还是 100 个连接,调用时都要把全部 fd 拷贝一次。

    • 例如原来监控 1000 个 fd,现在来了一个新连接,数组变成 1001 个,调用时需要把这 1001 个 fd 整个传到内核。
    • 所以每次调用开销是 O(N),与当前总 fd 数成正比。

2. epoll 的情况

  • 内核里有一个持久化的数据结构(红黑树 + 就绪链表)来保存“我关心的 fd”。

  • 新连接到来时,只需 调用一次 epoll_ctl(ADD, fd) 把这个单个 fd 注册进去,内核集合就更新了。

  • 后续的 epoll_wait 不需要再传全集合,只返回就绪 fd。

    • 所以新增 fd 的代价是 O(1)(单次 syscall,处理一个 fd),而等待就绪事件的代价是 O(#ready)

3. 所以性能差异体现在

  • select/poll:每次 wait 都要把“全量数组”搬到内核,新增一个 fd 后,每次 wait 的拷贝量都会增加。
  • epoll:新增 fd 时只需要告诉内核“再加一个”,以后 wait 的时候不用每次重新拷贝整个集合。

一句话总结

是的,差异就在于:

  • select/poll → 新增一个连接后,后续每次调用都要传 整个 fd 集合
  • epoll → 新增一个连接时,只需要传 那个新 fd 一次,之后 wait 再也不用传全集合。

使用水平触发模式时,当被监控的 Socket 上有可读事件发生时,服务器端不断地从 epoll_wait 中苏醒,直到内核缓冲区数据被 read 函数读完才结束——这里苏醒是什么意思

这个“苏醒”其实是个形象的说法,指的是:
线程在调用 epoll_wait 时会进入阻塞睡眠状态,当监控的 socket 上发生了指定事件(比如可读)时,内核会把这个阻塞的线程唤醒,让它从 epoll_wait 返回。


更精确的过程

  1. 你调用:

    int n = epoll_wait(epfd, events, maxevents, timeout);
    
    • 如果此时没有任何 fd 就绪,当前线程就会进入 睡眠状态,挂起在内核的等待队列里。
  2. 当某个被监控的 fd 上发生事件(例如 socket 收到数据,可读了):

    • 内核把这个事件加入 epoll 的“就绪队列”。
    • 内核检查有线程在 epoll_wait 上阻塞,就会唤醒这些线程
  3. 线程被唤醒后,epoll_wait 返回,你得到就绪事件。

    • 如果是 水平触发(LT),只要缓冲区里还有没读完的数据,fd 就一直处于就绪状态,下一次调用 epoll_wait 又会马上返回(继续“苏醒”)。
    • 只有当你把数据读干净(read 返回 EAGAIN),fd 才会变成未就绪,下次 epoll_wait 才会重新睡眠。

“苏醒”的本质

  • 内核通过 等待队列(wait queue) 机制把阻塞的线程放眠。
  • 当事件发生时,内核调用 wake_up 把线程从等待队列移出,让调度器把它重新放到可运行队列里。
  • 线程因此“苏醒”,从 epoll_wait 返回。

用白话类比

  • 睡眠:线程打盹,等着内核叫醒。
  • 苏醒:内核发现“喂,socket 来数据了!”,拍醒线程说“起来干活!”。
  • 水平触发下的不断苏醒:只要桌子上还有没吃完的饭(缓冲区里有数据),内核就会不停叫醒你;只有你把饭吃光(读干净),它才不再打扰你。

那epoll和Reactor之间的关系是什么?是不是Reactor基于epoll实现的

你问得很好 👍,这是很多人一开始都会混淆的地方。


1. epoll 是“机制”,Reactor 是“模式”

  • epoll:是 Linux 内核提供的 I/O 多路复用接口,是一种“系统调用机制”。它的职责就是:

    • 高效地监控一批 fd(socket)是否就绪;
    • 把就绪事件通知给用户态程序。
      👉 属于 操作系统层面的能力
  • Reactor:是一种 事件驱动编程模型/设计模式。它描述的是如何组织程序结构

    • 一个线程等待事件(epoll_wait 等),当有事件到来时,分发给对应的“事件处理器(Handler)”来处理。
      👉 属于 应用层面的架构模式

2. 关系

  • Reactor 模式通常用 epoll 来实现(在 Linux 下)。

  • 但 Reactor 并不依赖 epoll,它也可以用 select、poll、kqueue(BSD)、IOCP(Windows) 等机制来实现。

  • 换句话说:

    • epoll = 内核提供的工具
    • Reactor = 用这个工具组织起来的一种设计模式

3. 举例

比如一个典型的 Reactor 服务器流程:

while (true) {int n = epoll_wait(epfd, events, maxevents, -1); // 等待事件for (i = 0; i < n; i++) {if (events[i].data.fd == listen_fd) {// 有新连接 => 交给 Acceptoraccept_new_connection();} else {// 有数据可读/可写 => 交给对应的 Handlerhandler(events[i].data.fd);}}
}

这里:

  • epoll_wait 就是 内核机制
  • 整个 while 循环里“等待事件-分发-处理”的结构,就是 Reactor 模式

4. 总结

  • epoll操作系统提供的事件通知机制
  • Reactor一种事件驱动的编程模式
  • 在 Linux 里,Reactor 通常是 基于 epoll 来实现的,但在其他系统上也可能基于 poll、kqueue、IOCP 等。

哪些框架是基于Netty?

好问题 👍。Netty 本身就是一个 基于 Reactor 模式、封装了 Java NIO/epoll 的高性能网络通信框架。很多知名框架和中间件都直接或间接使用了 Netty 来处理底层网络通信。


常见基于 Netty 的框架/中间件

RPC / 微服务框架

  • Dubbo(阿里开源的 RPC 框架,核心通信基于 Netty)
  • gRPC-Java(Google 的 RPC 框架,Java 实现底层默认用 Netty)
  • Motan(新浪微博开源的 RPC 框架)
  • SOFARPC(蚂蚁金服开源的 RPC 框架,默认基于 Netty)

消息中间件

  • RocketMQ(阿里开源的分布式消息队列,通信层用 Netty)
  • Kafka(部分组件)(核心基于 NIO,部分工具/生态里使用 Netty)
  • ActiveMQ Artemis(底层网络层实现可选 Netty)

数据库相关

  • Redis 的部分 Java 客户端(如 Redisson 使用 Netty 管理连接池和通信)
  • Cassandra Java 驱动(使用 Netty 处理连接)
  • Elasticsearch Java 客户端(低层 IO 使用 Netty)

网关 / 代理

  • Zuul 2(Netflix 开源 API Gateway,底层通信是 Netty)
  • Spring Cloud Gateway(基于 Spring WebFlux,而 WebFlux 默认基于 Reactor-Netty)
  • gRPC-Gateway Java 生态实现

Web 服务器 / HTTP 框架

  • Reactor Netty(Spring 官方提供的 Netty 封装,Spring WebFlux 默认用它)
  • Vert.x(异步应用框架,默认底层用 Netty)
  • Play Framework(早期版本)(部分基于 Netty 的异步处理)

其他

  • Finagle(Twitter 开源的异步 RPC 框架,支持多协议,底层 Netty 实现之一)
  • HiveMQ(MQTT broker,基于 Netty 实现高并发连接)
  • Elasticsearch Transport 层(基于 Netty 处理节点间通信)

一句话总结

Netty = Java 世界的“网络通信基石”。
凡是需要 高并发网络通信 的 Java 框架/中间件,大概率都直接或间接用了 Netty,比如 Dubbo、RocketMQ、Spring Cloud Gateway、Elasticsearch、gRPC-Java

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/98295.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/98295.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/98295.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CF】Day139——杂题 (绝对值变换 | 异或 + 二分 | 随机数据 + 图论)

B. Meeting on the Line题目&#xff1a;思路&#xff1a;数形结合首先考虑如果没有 t 的影响该怎么写显然我们就是让最大时间最小化&#xff0c;那么显然选择最左端点和最右端点的中间值即可&#xff0c;即 (mi mx) / 2&#xff0c;那么现在有了 t 该怎么办我们不妨考虑拆开绝…

在 Ubuntu 上安装和配置 PostgreSQL 实录

一、查看ubuntu版本 lsb_release -a postgresq尽量安装在新的稳定版本的ubuntu上 二、安装postgresql 2.1 直接安装 sudo apt install postgresql 结果如下 2.2 使用PPA源安装 Ubuntu官方源提供了PostgreSQL的PPA(Personal Package Archive),通过PPA源安装可以确保获取…

WebGIS三维可视化 + 数据驱动:智慧煤仓监控系统如何破解煤炭仓储行业痛点

目录 一、项目背景&#xff1a;煤炭仓储管理的痛点与转型需求 二、建设意义&#xff1a;从 “被动管理” 到 “主动掌控” 的价值跃迁 三、项目核心&#xff1a;技术架构与核心目标的深度融合 四、数据与技术&#xff1a;系统稳定运行的 “双支柱” &#xff08;一&#x…

使用 Spring Security 实现 OAuth2:一步一步的操作指南

前言 OAuth 是一种授权框架&#xff0c;用于创建权限策略&#xff0c;并允许应用程序对用户在 HTTP 服务&#xff08;如 GitHub 和 Google&#xff09;上的账户进行有限访问。它的工作原理是允许用户授权第三方应用访问他们的数据&#xff0c;而无需分享他们的凭证。本文将指导…

VMware共享文件夹设置

启用共享文件夹 编辑虚拟机设置-选项-共享文件夹&#xff0c;上面的选项选择启用下面点击添加一个路径&#xff0c;跟着向导走 设置共享文件夹在主机的路径&#xff0c;和文件夹名称添加完成后可以点击这个共享文件夹条目&#xff0c;查看属性虚拟机里安装vm-tools sudo apt up…

华为云昇腾云服务

华为云&#xff0c;一切皆服务共建智能世界云底座面向未来的智能世界&#xff0c;数字化是企业发展的必由之路。数字化成功的关键是以云原生的思维践行云原生&#xff0c;全数字化、全云化、AI驱动&#xff0c;一切皆服务。华为云将持续创新&#xff0c;携手客户、合作伙伴和开…

Axum 最佳实践:如何构建优雅的 Rust 错误处理系统?(三)

引言 作为开发者&#xff0c;我们都经历过这样的场景&#xff1a;项目上线后&#xff0c;你打开日志监控&#xff0c;铺天盖地的 500 Internal Server Error 扑面而来。这些错误像个黑洞&#xff0c;吞噬着你的调试时间&#xff0c;你甚至不知道它们是从数据库查询失败&#x…

MySQL高可用方案解析:从复制到云原生

MySQL 的高可用 (High Availability, HA) 方案旨在确保数据库服务在硬件故障、软件崩溃、网络中断或计划维护时仍能持续可用&#xff0c;最小化停机时间&#xff08;通常目标为 99.9% 至 99.999% 可用性&#xff09;。以下是 MySQL 领域成熟且广泛应用的几种主流高可用方案&…

腾讯云语音接口实现会议系统

1.前言 在现代企业协作环境中&#xff0c;高效的会议管理是提升团队生产力的关键。本文将深入解析一个完整的会议管理系统&#xff0c;涵盖从会议创建到总结生成的完整生命周期。该系统构建一个基于AI技术的智能会议系统&#xff0c;实现会议全流程的智能化管理&#xff0c;包括…

【LeetCode 每日一题】1277. 统计全为 1 的正方形子矩阵

Problem: 1277. 统计全为 1 的正方形子矩阵 文章目录整体思路完整代码时空复杂度时间复杂度&#xff1a;O(m * n)空间复杂度&#xff1a;O(m * n)整体思路 这段代码旨在解决一个经典的二维矩阵问题&#xff1a;统计全为 1 的正方形子矩阵个数 (Count Square Submatrices with …

【论文阅读】MedResearcher-R1: 基于知识引导轨迹合成框架的专家级医学深度研究员

论文链接&#xff1a;https://arxiv.org/pdf/2508.14880 【导读】当通用大模型还在“背题库”时&#xff0c;蚂蚁集团联合哈工大推出的 MedResearcher-R1 已把“临床查房”搬进训练场&#xff01;这篇 2025 年 9 月发布的论文&#xff0c;首次让开源 32B 模型在医学深度研究基准…

基于大语言模型的事件响应优化方案探索

程序员的技术管理推荐阅读 当愿望遇上能力鸿沟&#xff1a;一位技术管理者眼中的团队激励思考 从“激励”到“保健”&#xff1a;80后与90后程序员&#xff0c;到底想要什么&#xff1f; 从“激励”到“保健”&#xff1a;80后与90后程序员&#xff0c;到底想要什么&#xff1f…

数字化浪潮下,传统加工厂如何智能化转型?

在制造业向高端化、服务化升级的今天&#xff0c;传统加工厂正面临前所未有的挑战。订单碎片化、人力成本攀升、设备OEE&#xff08;综合效率&#xff09;长期低于50%、质量波动难以追溯……这些痛点不仅压缩着企业利润空间&#xff0c;更让其在应对市场需求变化时显得迟缓。当…

谓语动词选择指南

文章目录谓语动词的重要性谓语动词类别一. 助动词1. be&#xff08;am, is, are, was, were, been, being&#xff09;表示 存在、状态、身份、特征。2. have&#xff08;have, has, had&#xff09;表示 拥有、经历 或 完成时态的助动词。3. do&#xff08;do, does, did&…

代码随想录学习摘抄day7(二叉树11-21)

一个朴实无华的目录题型226.翻转二叉树思路&#xff1a;把每一个节点的左右孩子交换一下101. 对称二叉树思路&#xff1a;使用队列来比较两个树&#xff08;根节点的左右子树&#xff09;是否相互翻转222.完全二叉树的节点个数思路&#xff1a;本题直接就是求有多少个节点&…

Python+DRVT 从外部调用 Revit:批量创建楼板

今天继续批量创建常用的基础元素&#xff1a;楼板。这次以简单的轮廓为矩形的楼板为例。让我们来看一看如何让Revit自动干活&#xff1a; from typing import List import math # drvt_pybind 支持多会话、多文档&#xff0c;先从简单的单会话、单文档开始 # MyContext是在Pyt…

猿辅导数据分析面试题及参考答案

给定用户成绩表,编写SQL查询排名靠前的用户(例如前10名),并说明rank()和dense_rank()的区别。 要查询成绩表中排名靠前的用户(如前10名),需先明确排名依据(通常为成绩降序),再通过排序和限制结果行数实现。假设用户成绩表名为user_scores,包含user_id(用户ID)和s…

在树莓派集群上部署 Distributed Llama (Qwen 3 14B) 详细指南

项目地址&#xff1a;https://github.com/b4rtaz/distributed-llama 本文档将指导您如何使用一个树莓派5作为Root节点和三个树莓派4作为Worker节点&#xff0c;共同搭建一个4节点的分布式LLM推理集群&#xff0c;并运行10.9GB的Qwen 3 14B模型。 中间要用到github和huggingface…

C++ 容器——unordered_xxx

自 C11 开始&#xff0c;STL 引入了基于 hash table 的 unordered_set、unordered_map 等容器&#xff0c;正如其名它们是无序容器。一定数量&#xff08;据说有测试数据是10000000&#xff09;元素时无序容器的性能要比对应的有序容器优。一、容器数据结构unordered_set、unor…

分布式常见面试题整理

一、分布式理论&#xff1a; CAP理论 分布式系统最多同时满足一致性&#xff08;C&#xff09;、可用性&#xff08;A&#xff09;、分区容错性&#xff08;P&#xff09;中的两个&#xff0c;无法三者兼得。 BASE理论 对CAP中一致性和可用性的权衡&#xff0c;强调基本可用&a…