首页 > 其他分享 >Select,poll,epoll和IO多路复用和NIO

Select,poll,epoll和IO多路复用和NIO

时间:2024-11-16 17:44:04浏览次数:3  
标签:NIO 多路复用 epoll 描述符 IO Poll Select

Select,poll,epoll和IO多路复用和NIO

  • IO 多路复用:是一种 I/O 处理机制,它允许单个线程同时处理多个 I/O 流(如多个文件描述符对应的网络连接、文件操作等)的输入输出操作,通过一种机制来监听这些 I/O 流的状态变化(如可读、可写等),一旦某个 I/O 流有状态变化,就可以对其进行相应的处理。Select、Poll、Epoll 都是实现 IO 多路复用的具体技术手段,它们属于 IO 多路复用这个大的范畴。

  • NIO(New Input/Output):是 Java 中对传统 I/O(BIO,Blocking I/O)的一种改进,它提供了非阻塞 I/O 和基于通道(Channel)与缓冲区(Buffer)的 I/O 操作方式等特性。NIO 在实现过程中也会用到 IO 多路复用的思想,并且在 Java 的 NIO 实现中,底层实际上是可以基于 Select、Poll 或 Epoll(取决于不同的操作系统和 Java 运行时环境)等方式来实现对多个 I/O 事件的监听和处理,所以 NIO 与 IO 多路复用紧密相关,它是在 Java 语言层面应用 IO 多路复用机制的一种体现。

Select,poll,epoll区别

他们是NIO中多路复用的三种实现机制,是由Linux操作系统提供的。

用户空间和内核空间: 操作系统为了保护系统安全,将内核划分为两个部分,一个是用户空间,一个是内核空间。用户空间不能直接访问底层的硬件设备,必须通过内核空间。

文件描述符 File Descriptor(FD): 是一个抽象的概念,形式上是一个整数,实际上是一个索引值。指向内核中为每个进程维护 进程所打开的文件的记录表。当程序打开一个文件或者创建一个文件时,内核就会向进程返回一个FD。Unix,Linux中才有

select机制: 会维护一个FD的结合 fd_set,将fd_set从用户空间复制到内核空间,激活socket。 x64位机器上受限 2048, fd_set是一个数组结构

Poll机制: 和selecter机制是差不多的,把fd_set结构进行了优化,FD集合的大小就突破了操作系统的限制。 pollfd结构来代替fd_set,通过链表实现的。操作跟Selecter机制一样都是遍历FD集合

EPoll: Event Poll.Epoll不再扫描所有的FD,只将用户关心的FD的事件存放到内核的一个事件表当中。这样,可以减少用户空间与内核空间之前需要拷贝的数据

  • Select,poll,epoll都是底层C++的API

java的NI0当中是用的那种机制?

可以查看DefaultSelectorProvider类的源码,

在windows下,WindowsSelectorProvider. 而Linux下,根据Linux的内核版本,2.6版本以上,就是EPollSelectorProvider,否则就是默认的PollSelectorProvider.

1. Select

  • 实现原理:Select 通过一个文件描述符集合fd_set(通常有三个集合,分别对应可读、可写和异常事件)来监听多个 I/O 流的状态变化。在调用 Select 函数时,它会遍历这个集合中的所有文件描述符,逐个检查它们是否有对应的可读、可写或异常事件发生。如果有事件发生,Select 会返回,并告知哪些文件描述符发生了何种事件,然后程序就可以针对这些发生事件的文件描述符进行相应的处理。

  • 性能特点:

    • 随着监听的文件描述符数量增加,性能会显著下降。因为每次调用 Select 都需要遍历整个文件描述符集合来检查状态变化,当文件描述符数量很大时,遍历的开销就会变得很大。

    • 每次调用 Select 后,返回的结果只是告知哪些文件描述描述符有事件发生,但并没有提供详细的事件信息,例如对于可读事件,它不会告诉你到底有多少数据可读,还需要进一步通过读取操作来确定。

  • 平台支持:Select 是最早1984年出现的 IO 多路复用技术,几乎在所有的操作系统上都有支持,具有很好的跨平台性。

2. Poll

  • 实现原理:Poll 的工作原理与 Select 类似,也是通过一个结构体数组pollfd(类似文件描述符集合)来监听多个 I/O 流的状态变化。不同的是,Poll 使用的结构体数组可以动态分配大小,不像 Select 那样有固定大小的集合限制。在调用 Poll 函数时,同样会遍历这个结构体数组来检查各 I/O 流的状态变化,一旦有事件发生,Poll 会返回并告知相关信息。

  • 性能特点:

    • 虽然 Poll 解决了 Select 文件描述符集合固定大小的问题,但它在性能上与 Select 类似,当监听的文件描述符数量较多时,遍历结构体数组的开销同样会导致性能下降。

    • 与 Select 一样,返回的结果也只是告知哪些文件描述符有事件发生,没有提供更详细的事件信息,需要进一步操作来确定具体情况。

  • 平台支持:Poll 也具有较好的跨平台性,在很多操作系统上都有支持,不过在实际应用中,由于性能方面的原因,使用频率相对 Select 可能会低一些。1997年

3. Epoll

  • 实现原理:Epoll 是 Linux 特有的一种高性能的 IO 多路复用技术。它采用了事件驱动的设计思想,通过在内核中创建一个红黑树来管理所有监听的文件描述符,同时还有一个就绪队列来存放已经发生事件的文件描述符。当有事件发生时,内核会直接将发生事件的文件描述符放入就绪队列,而不是像 Select 和 Poll 那样需要遍历整个集合或数组来查找。应用程序只需要从就绪队列中获取发生事件的文件描述符并进行处理即可。

  • 性能特点:

    • 具有非常高的性能,尤其是在监听大量文件描述符时优势明显。因为它不需要遍历所有监听的文件描述符来查找发生事件的文件描述符,大大减少了遍历开销。

    • 提供了更详细的事件信息,例如对于可读事件,它可以告知有多少数据可读等详细情况,这使得应用程序在处理 I/O 事件时更加高效。

  • 平台支持:Epoll 仅在 Linux 操作系统上有支持,不具有跨平台性。

4. NIO(从 Java 角度看)

  • 实现原理:Java 的 NIO 基于通道(Channel)和缓冲区(Buffer)进行 I/O 操作。它提供了非阻塞 I/O 模式,即当进行读或写操作时,如果没有数据可读或可写,不会像传统的 BIO 那样阻塞等待,而是立即返回并告知当前状态。在监听多个 I/O 事件方面,Java 的 NIO 底层会根据不同的操作系统采用不同的 IO 多路复用实现方式(如在 Linux 下可能采用 Epoll,在 Windows 下可能采用类似 Select 的实现,在 Mac OS 等其他操作系统下也有相应的实现方式),通过这些方式来实现对多个 I/O 通道的监听,一旦某个通道有事件发生,就可以进行相应的处理。

  • 性能特点:

    • 相比于传统的 BIO,NIO 的非阻塞特性使得它在处理多个 I/O 事件时可以更高效地利用系统资源,减少了因阻塞等待而浪费的时间。

    • 不过,NIO 的实现相对复杂一些,尤其是在处理复杂的 I/O 场景时,需要对通道、缓冲区以及事件监听等方面有较好的理解和运用。

  • 平台支持:Java 的 NIO 具有良好的跨平台性,因为它会根据不同的操作系统采用合适的底层 IO 多路复用实现方式来保证在各种操作系统上都能正常运行。

综上所述,Select、Poll、Epoll 是实现 IO 多路复用的不同技术手段,各有其性能特点和适用场景,而 NIO 是 Java 中应用 IO 多路复用思想的一种实现,它与这些 IO 多路复用技术紧密相关,并且在不同的操作系统下会依托不同的 IO 多路复用实现方式来实现其功能。

标签:NIO,多路复用,epoll,描述符,IO,Poll,Select
From: https://blog.csdn.net/qq_62097431/article/details/143607435

相关文章

  • CCS XDS100 V1仿真器配置Target Configurations设备栏空白解决方法(仿真器驱动更新)
    设备:普中科技TMS320F28335开发板仿真器:XDS100v1问题:打开CCS后,导入工程之后,要配置TargetConfigurations的时候,选择了TexasInstrumentsXDS100v1USB,但是下方的设备选项是空白,没有出现芯片选项。解决方法:(1)打开我的电脑-管理-设备管理器,检查是否出现TI端口,如下图(2......
  • 【转载】遗传算法—Exploring NEAT-Neuroevolution of Augmenting Topologies
    原文地址:https://hunterheidenreich.com/posts/neuroevolution-of-augmenting-topologies/AWorldofNeuroEvolutionRecently,I’vebeendoingalotofreadingaboutsomethingcalledneuroevolution.Atahigh-level,theideaisverysimple.Insteadofrelyingo......
  • CSS(7):定位position:相对定位(relative)、绝对定位(absolute)、固定定位(fixed)和静态定位(st
    一.定位:将盒子定在某一个位置,其规则为:定位=定位模式+边偏移 。二:定位模式1.static静态定位:元素无设置的时候就是static        “position:static;”2.relative相对定位:相对于当前位置进行移动,通过设置偏移属性(top、right、bottom、left)来使其在水平和垂直......
  • localStorage和sessionStorage存储封装
    constcreateStorageProxy=(target={},type:'local'|'session')=>{conststorage=type==='local'?localStorage:sessionStorage;returnnewProxy(target,{get(obj:Record<string,any>,prop:string......
  • 你不应错过的Dario和Sam的五小时访谈-AGI的进展
      每周跟踪AI热点新闻动向和震撼发展想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领域的领跑者。点击订阅,与未来同行!订阅:https://......
  • (IOC&DI)部门信息管理功能分层解耦优化
    一、优化分析@RestControllerpublicclassDeptController{privateDeptServiceimplService=newDeptServiceimpl(); 在之前的代码每一层在调取上一层的业务功能的时候都是new一个新对象出来之后再进行调取,但是这样的做法层与层之间的耦合太强,而且不利于代码的维......
  • Java反序列化-Commons Collections3利用链分析详解
    介绍CC3与CC1和CC6的主要区别在于,CC1和CC6依赖反射机制来执行Runtime.getRuntime().exec()等危险命令,而如果服务器将这些方法列入黑名单,这两种方式就会失效。相比之下,CC3通过类加载器动态加载恶意类来执行危险函数,绕过黑名单限制,从而达到命令执行的目的。公众号:T......
  • axios的post请求,数据为什么要用qs处理?什么时候不用?
    在使用Axios进行HTTP请求时,特别是在进行POST请求时,是否需要对数据进行qs(Querystring)处理主要取决于后端API接收数据的格式(Content-Type)以及你的具体需求。为什么有时需要用qs处理数据?后端期望application/x-www-form-urlencoded格式的数据:如果后端API设计为接收application/......
  • 【Azure App Service】在App Service中调用Stroage SDK上传文件时遇见 System.OutOfMe
    问题描述部署.NET应用到AppService中,应用中调用StorageAccount的SDK上传文件到Blob中。只是比较高频率在UploadAsync方法中遇见:OutOfMemoryException异常信息ERRORMicrosoft.AspNetCore.Server.Kestrel.?[?]-MESSAGE:Connectionid"0HN3UB91BK6BS",Requestid"0H......
  • 在 tsconfig.json 文件中,compilerOptions.types 字段用于指定 TypeScript 编译器应该
    在tsconfig.json文件中,compilerOptions.types字段用于指定TypeScript编译器应该包含的类型声明文件。这些类型声明文件提供了类型信息,使得TypeScript能够在编译时进行类型检查和提供智能提示。你提到的配置项指定了几个常用的类型声明文件,下面是对这些配置项的详细解释:配......