深度剖析并发I/O模型select、poll、epoll与IOCP核心机制

核心概要selectpollepollIOCP 是四种用于提升服务器并发处理能力的I/O模型或机制。前三者主要属于I/O多路复用范畴,允许单个进程或线程监视多个I/O流的状态;而 IOCP 则是一种更为彻底的异步I/O模型

一、引言:为何需要这些技术?

在网络服务器开发中,一个核心挑战是如何高效地处理大量并发连接。传统的阻塞式I/O模型(一个线程处理一个连接,并在I/O操作时阻塞)在并发量高时会导致线程数量激增,带来巨大的上下文切换开销和资源消耗。为了解决这一问题,发展出了I/O多路复用和异步I/O技术。

二、I/O多路复用技术:select, poll, epoll

I/O多路复用允许单个进程监视多个文件描述符(FD),一旦某个或某些FD就绪(例如,可读或可写),便通知应用程序进行相应的I/O操作。应用程序本身在调用这些多路复用函数时可能会阻塞,但一旦收到通知,后续的I/O操作(如read, write)通常可以非阻塞地执行,或者至少是已知的可操作状态。

1. select

一句话介绍select 是一种传统的I/O多路复用机制,它允许程序监视一组文件描述符,等待一个或多个描述符变为就绪状态。

工作机制

  • 应用程序通过 fd_set 数据结构向内核注册需要监视的读、写和异常文件描述符集合。

  • 调用 select 函数,该调用会阻塞,直到有文件描述符就绪或超时。

  • select 返回后,内核会修改传入的 fd_set 来指示哪些文件描述符已就绪。

  • 应用程序需要遍历整个 fd_set 来找出具体就绪的文件描述符,并对其进行操作。

主要特点

  • 跨平台性:作为早期标准,select 具有良好的跨平台兼容性。

  • 文件描述符数量限制:受 FD_SETSIZE 宏的限制(通常为1024或2048),能够监视的文件描述符数量有限。

  • 性能开销:

    • 每次调用都需要将 fd_set 在用户空间和内核空间之间完整拷贝。

    • 内核在检查时需要遍历所有被监视的FD。

    • 应用程序在返回后也需要遍历 fd_set 以确定哪些FD就绪。

举例:想象一位老派的邮局分拣员。每次来一批信件(FD集合),他都要把所有信箱(所有被监视的FD)检查一遍,看看哪些信箱里有新信(FD就绪)。即使只有少数信箱有信,他也得全部看一遍。而且他能管理的信箱总数也是固定的

2. poll

一句话介绍pollselect 的一种改进,它解决了文件描述符数量的限制,并使用不同的数据结构来管理监视的描述符。

工作机制

  • 应用程序使用一个 pollfd 结构体数组来指定要监视的文件描述符及其关心的事件(如 POLLIN 表示可读,POLLOUT 表示可写)。

  • 调用 poll 函数,该调用会阻塞,直到有描述符就绪或超时。

  • poll 返回后,内核会在 pollfd 结构体中的 revents 字段中标示出哪些文件描述符发生了哪些事件。

  • 应用程序需要遍历这个 pollfd 数组来找出就绪的描述符。

主要特点

  • 无文件描述符数量硬性限制:监视的FD数量仅受系统资源限制。

  • 数据结构改进:使用 pollfd 结构体,每个结构体对应一个FD,避免了 selectfd_set 的固定大小问题。

  • 性能开销依然存在:

    • 每次调用仍需将 pollfd 数组在用户空间和内核空间之间拷贝。

    • 内核和应用程序仍需遍历所有被监视的FD(即使只有少数就绪)。

3. epoll (Linux Specific)

一句话介绍epoll 是 Linux 内核提供的高效I/O多路复用机制,它显著改善了处理大量并发连接时的性能。

工作机制

epoll 的使用分为三个主要步骤:

  1. epoll_create / epoll_create1:在内核中创建一个 epoll 实例,返回一个代表该实例的文件描述符。

  2. epoll_ctl:向 epoll 实例中添加(EPOLL_CTL_ADD)、修改(EPOLL_CTL_MOD)或删除(EPOLL_CTL_DEL)需要监视的文件描述符及其关心的事件。这些信息由内核维护,不需要重复传递。

  3. epoll_wait:阻塞等待已注册的文件描述符上发生就绪事件。与 selectpoll 不同,epoll_wait 仅返回那些已经就绪的文件描述符,而不是所有被监视的描述符。

主要特点

  • 高效性:

    • 事件驱动:内核负责跟踪FD的状态,当FD就绪时,会将其放入一个就绪列表中。epoll_wait 只需检查此列表。

    • 减少数据拷贝:FD集合由内核管理,epoll_wait 调用时无需拷贝整个FD集合。

    • 无需遍历:应用程序直接从 epoll_wait 的返回中获取就绪的FD列表,避免了轮询。

  • 支持边缘触发 (ET) 和水平触发 (LT):

    • LT (Level Triggered, 默认):只要FD处于就绪状态,epoll_wait 就会通知。

    • ET (Edge Triggered):仅当FD状态从未就绪变为就绪时通知一次。这要求应用程序一次性处理完所有可用数据,编程更复杂,但能进一步减少 epoll_wait 的调用次数。

  • Linux 特有:不具备跨平台性。

举例epoll 就像一个现代化的智能快递柜系统。快递员(内核)把包裹(数据)放进柜子(FD就绪)后,系统会自动给收件人(应用程序)发送一条取件码(epoll_wait 返回就绪的FD)。收件人凭码直接取件,无需检查每个柜子。

三、异步I/O模型:IOCP (Windows Specific)

异步I/O (Asynchronous I/O) 模型与I/O多路复用有本质区别。在异步I/O中,应用程序发起一个I/O操作后立即返回,不等待操作完成。操作系统内核负责完成整个I/O过程(包括将数据从内核空间拷贝到用户指定的缓冲区),并在操作完成后通过特定机制通知应用程序。

IOCP (I/O Completion Ports)

一句话介绍IOCP 是 Windows 平台上一种高效、可伸缩的异步I/O模型,专为处理大量并发I/O操作设计。

工作机制

  1. 创建完成端口:应用程序首先创建一个I/O完成端口 (CreateIoCompletionPort)。

  2. 关联设备句柄:将需要进行异步I/O操作的设备句柄(如套接字、文件句柄)与该完成端口关联。

  3. 发起异步I/O操作:应用程序调用异步I/O函数(如 ReadFile, WriteFile, WSASend, WSARecv),并提供一个 OVERLAPPED 结构和一个可选的完成键。这些函数会立即返回,表示操作已成功提交给操作系统。

  4. 操作系统处理:操作系统内核在后台执行实际的I/O操作。

  5. 完成通知:当I/O操作完成(或失败)后,操作系统会将一个包含操作结果和 OVERLAPPED 结构指针的“完成包”排入与设备句柄关联的完成端口队列中。

  6. 获取完成状态:应用程序的工作线程调用 GetQueuedCompletionStatus 函数,该函数会阻塞等待,直到完成端口队列中有完成包。获取到完成包后,线程便可以处理已完成的I/O操作结果(数据已在用户缓冲区)。

主要特点

  • 真正的异步:应用程序不参与实际的I/O数据传输过程,仅发起请求和处理完成通知。

  • 高效的线程管理IOCP 能够与线程池良好集成。操作系统会根据I/O负载和CPU核心数量智能地调度和唤醒工作线程,避免了过多的线程创建和上下文切换。

  • 高吞吐量和伸缩性:非常适合构建高性能服务器应用。

  • Windows 特有:不具备跨平台性。

举例IOCP 就像一个大型中央厨房的外卖系统。顾客(应用程序)通过App下单(发起异步I/O),然后就可以去做别的事情了。中央厨房(操作系统)负责烹饪并打包(执行I/O)。菜品完成后,系统会通知骑手(工作线程)去指定的取餐点(完成端口)取餐并配送(处理完成的I/O)。骑手们被高效地调度,确保外卖准时送达。


四、总结

特性selectpollepoll (Linux)IOCP (Windows)
模型同步I/O多路复用同步I/O多路复用同步I/O多路复用异步I/O
核心思想监视FD,等待就绪通知监视FD,等待就绪通知高效监视FD,仅返回就绪FD发起I/O,等待操作完成通知
数据传输程序在收到通知后自行读写程序在收到通知后自行读写程序在收到通知后自行读写内核完成数据传输
效率低,受FD数量和轮询限制一般,不受FD数量限制,但仍需轮询高,事件驱动,无需轮询非常高,内核级异步,线程调度优化
跨平台性良好较好差 (Linux)差 (Windows)

选择哪种技术取决于具体的应用场景、目标平台以及对性能和并发能力的要求。对于需要跨平台且并发要求不极端的情况,selectpoll 可能是简单选择。对于Linux平台下追求极致性能的高并发服务器,epoll 是首选。对于Windows平台下的高性能服务器,IOCP 提供了强大的异步处理能力。

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

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

相关文章

microsoft中word如何添加个人签名

https://support.microsoft.com/zh-cn/office/%E6%8F%92%E5%85%A5%E7%AD%BE%E5%90%8D-f3b3f74c-2355-4d53-be89-ae9c50022730 插入签名图片 图片格式选择裁剪合适的大小 使用的签名如果不是白色纸张的话可以重新着色 依次点击图片格式——颜色——重新着色——黑白50% 设置透…

linux初识--基础指令

Linux下基础指令 ls 指令 语法: ls [ 选项 ] [ ⽬录或⽂件 ] 功能:对于⽬录,该命令列出该⽬录下的所有⼦⽬录与⽂件。对于⽂件,将列出⽂件名以及其他信 息。 常⽤选项: -a 列出⽬录下的所有⽂件,包括以…

实战:Dify智能体+Java=自动化运营工具!

我们在运营某个圈子的时候,可能每天都要将这个圈子的“热门新闻”发送到朋友圈或聊天群里,但依靠传统的实现手段非常耗时耗力,我们通常要先收集热门新闻,再组装要新闻内容,再根据内容设计海报等。 那怎么才能简化并高…

RabbitMQ可靠传输——持久性、发送方确认

一、持久性 前面学习消息确认机制时,是为了保证Broker到消费者直接的可靠传输的,但是如果是Broker出现问题(如停止服务),如何保证消息可靠性?对此,RabbitMQ提供了持久化功能: 持久…

(Java基础笔记vlog)Java中常见的几种设计模式详解

前言: 在 Java 编程里,设计模式是被反复使用、多数人知晓、经过分类编目的代码设计经验总结。他能帮助开发者更高效地解决常见问题,提升代码的可维护性、可扩展性和复用性。下面介绍Java 中几种常见的设计模式。 单例模式(Singlet…

(8)Spring Boot 原生镜像支持

Spring Boot 原生镜像支持 👉 点击展开题目 在Spring Boot 3.x中,如何设计一个支持GraalVM原生镜像的微服务?需要特别注意哪些限制? 📌 Spring Boot 3.x 原生镜像概述 Spring Boot 3.x 通过 Spring Native 项目提供了对 GraalVM 原生镜像的一流支持,使开发者能够将 S…

不使用SOAP,从PDF表单连接数据库

不使用SOAP协议,通过XFDF格式实现PDF表单与数据库交互的方法。该方法兼容免费的Adobe Reader,且无需特殊权限设置。 背景与问题 历史方案: Adobe曾提供ADBC接口(基于ODBC),但在Acrobat 9后被移除。SOAP方案在免费版Rea…

HTTP由浅入深

文章目录 概述特点URL HTTP 与 HTTPS概述HTTP 工作原理HTTPS 的作用区别总结 请求报文请求行常见请求方法请求头请求体Content-Type 详解常见场景 Content-Type 对应关系 响应报文响应行状态码详解1xx:信息响应(Informational)2xx&#xff1a…

Redis淘汰策略

Redis有八种淘汰策略 noeviction :不进行淘汰,直接报错。allkeys-lru :随机淘汰最久未使用的键。volatile-lru :从设置了过期时间的键中,随机淘汰最久未使用的键。allkeys-random :随机淘汰某个键。volati…

Maven打包SpringBoot项目,因包含SpringBootTest单元测试和Java预览版特性导致打包失败

SpringBoot启用Java预览版特性&#xff08;无测试类&#xff09; 在pom.xml文件中加入以下配置表示启用Java预览版 <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration>…

Makefile快速入门

简介‌&#xff1a; ‌ Makefile‌ 是一种用于自动化构建和管理软件项目的工具文件&#xff0c;通常与 make 命令配合使用。它通过定义‌规则‌&#xff08;rules&#xff09;来指定如何从源文件生成目标文件&#xff08;如可执行程序或库&#xff09;&#xff0c;并自动…

RISC-V 开发板 MUSE Pi Pro OpenCV结合Gstreamer实时显示CSI摄像头

视频讲解&#xff1a;RISC-V 开发板 MUSE Pi Pro OpenCV结合Gstreamer实时显示CSI摄像头_哔哩哔哩_bilibili RISC-V 开发板 MUSE Pi Pro OpenCV结合Gstreamer实时显示CSI摄像头 安装opencv相关库 sudo apt install libopencv-dev python3 python3-opencv 测试使用的CSI摄像头…

如何用JAVA手写一个Tomcat

一、初步理解Tomcat Tomcat是什么&#xff1f; Tomcat 是一个开源的 轻量级 Java Web 应用服务器&#xff0c;核心功能是 运行 Servlet/JSP。 Tomcat的核心功能&#xff1f; Servlet 容器&#xff1a;负责加载、实例化、调用和销毁 Servlet。 HTTP 服务器&#xff1a;监听端口…

短剧系统开发与抖音生态融合:短视频时代的新风口与商业机遇

在短视频内容井喷的时代&#xff0c;“短剧”作为一种新兴内容形态&#xff0c;正以惊人的速度抢占用户注意力。抖音、快手等平台日均播放量破亿的短剧作品&#xff0c;不仅催生了新的内容创作风口&#xff0c;更推动了短剧系统开发的巨大市场需求。本文将深度解析短剧系统开发…

《云原生安全攻防》-- K8s日志审计:从攻击溯源到安全实时告警

当K8s集群遭受入侵时&#xff0c;安全管理员可以通过审计日志进行攻击溯源&#xff0c;通过分析攻击痕迹&#xff0c;我们可以找到攻击者的入侵行为&#xff0c;还原攻击者的攻击路径&#xff0c;以便修复安全问题。 在本节课程中&#xff0c;我们将介绍如何配置K8s审计日志&am…

3dczml时间动态图型场景

在cesium中我们了可以使用czml数据来生成可以随时间变化而变化的物体. 首先导入czml数据 设置时间范围 id: "point" //物体在什么时间范围可用 availability:"2012-08-04T16:00:00Z/2012-08-04T16:05:00Z"position:{ //设置物体的起始时间 epoch:"…

超小多模态视觉语言模型MiniMind-V 训练

简述 MiniMind-V 是一个超适合初学者的项目&#xff0c;让你用普通电脑就能训一个能看图说话的 AI。训练过程就像教小孩&#xff1a;先准备好图文材料&#xff08;数据集&#xff09;&#xff0c;教它基础知识&#xff08;预训练&#xff09;&#xff0c;再教具体技能&#xf…

01-jenkins学习之旅-window-下载-安装-安装后设置向导

1 jenkins简介 百度百科介绍&#xff1a;Jenkins是一个开源软件项目&#xff0c;是基于Java开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件项目可以进行持续集成。 [1] Jenkins官网地址 翻译&…

VPLC (VPLCnext) K8S

前序 在接触Virtual PLCnext Control的时候&#xff0c;我想过好几次如何将它运行在k8s上&#xff0c;由于对k8s的熟悉程度不够&#xff0c;跌跌撞撞尝试了很久&#xff0c;终于把vPLC部署在单机版的k8s上了。&#xff08;此教程仅为demo阶段&#xff0c;此教程仅为demo阶段&a…

OPC Client第5讲(wxwidgets):初始界面的事件处理;按照配置文件初始化界面的内容

接上一讲&#xff0c;即实现下述界面的事件处理代码&#xff1b;并且按照配置文件初始化界面的内容&#xff08;三、&#xff09; 事件处理的基础知识&#xff0c;见下述链接五、 OPC Client第3讲&#xff08;wxwidgets&#xff09;&#xff1a;wxFormBuilder&#xff1b;基础…