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

I/O多路复用

一.什么是I/O多路复用

核心思想:通过一个线程同时管理多个 Socket(文件描述符),在一个线程内同时检测 多个连接的状态(如是否可读/可写),从而实现高效的并发处理。在 Linux中,常见的 I/O 多路复用技术包括selectpollepoll

二.为什么要使用I/O多路复用

1.最基础的TCP Socket编程使用的是阻塞I/O模型:每次进行I/O操作(如读 写数据),调用的线程会被阻塞,直到操作完成为止。在这种模型下,一个线程 只能处理一个客户端的请求,也就是“一对一通信。如果需要同时处理多个客户 \端连接,就必须为每个连接创建一个独立的线程或进程。当客户端数量很少时, 这种方式是可行的。但如果有成千上万个客户端(如 C10K问题,1万个并发客 户端连接),线程/进程的调度和资源占用(如内存)会成为瓶颈。

2.在传统的多线程/多进程模型中:每个客户端连接对应一个独立的线程或进程。 当有数据读写时,线程阻塞在对应的 Socket上,直到数据准备好。当客户端数 量很少时,这种方式是可行的,但如果有成千上万个客户端(如 C10K问题,1 万个并发客户端连接),线程/进程上下文切换开销会很大,且每个线程/进程都有一定的内存开销(如栈内存、线程控制块等),此时内存和调度开销的将变得不可接受。

三.selectpoll的工作原理

1.select 实现多路复用的方式是,将已连接的Socket(文件描述符)都放到一个文件描述 符集合,然后调用select函数将文件描述符集合拷贝到内核里,让内核遍历整个文件描述 符集合,检测每个Socket的状态,如果某些Socket有事件(如数据到达或可写),内核会设置对应的状态。接着内核将检测结果(整个 Socket集合)拷贝回用户态,用户程序需要再次遍历整个集合,找到可读或可写的 Socket,对其处理。

缺点:需要进行2次「遍历」文件描述符集合,一次是在内核态里,一个次是在用户态里 ,而且还会发生2次「拷贝」文件描述符集合,先从用户空间传入内核空间,由内核修改后,再传出到用户空间中。

2.selectpoll的区别:select使用固定长度的BitsMap,表示文件描述符集合,而且所支持的文件描述符的个数是有限制的,poll使用动态数组,以链表形式来组织,突破了select 的文件描述符个数限制,当然还会受到系统文件描述符限制。 但是 pollselect并没有太大的本质区别,都是使用「线性结构」存储进程关注的Socket集合,因此都需要遍历文件描述符集合来找到可读或可写的Socket,时间复杂度为O(n),而且也需要在用户态与内核态之间拷贝文件描述符集合,这种方式随着并发数上来,性能的损耗会呈指数级增长。

3.epoll的工作原理

epoll的改进:

1. 高效的红黑树管理: epoll 在内核中使用红黑树存储待监控的Socket集合。 优势: 插入、删除、修改 Socket的时间复杂度为O(log n)。 相比于 select/poll每次都拷贝整个Socket集合, epoll 只需在第一次时添加到红黑树即可,无需重复拷贝,红黑树会一直维护这些描述符,直到显式地移除它们。

2. 事件驱动机制:epoll 使用事件驱动机制,即内核会监听事件的发生链表记录就绪事件: 内核会将发生事件的 Socket(如有数据到达或可写的Socket)通过回调函数加入到一个就绪链表中。应用程序只需要处理这个链表中的 Socket,无需遍历整个集合。

epoll支持两种事件触发模式:水平触发:默认模式,和select/poll一样。当被监控的Socket上有可读事件发生时,内核会一直通知应用程序,直到数据被read函数完全读取。边缘触发:当被监控的Socket描述符上有可读事件发生时,内核只会通知应用程序一 次,需要应用程序收到通知后尽可能一次读取完所有数据,以免错失读写机会。所以,程序会循环从socket中读写数据,那么如果文件描述符是阻塞的,没有数据可读写时,进程会阻塞在读写函数那里,程序就没办法继续往下执。所以,边缘触发模式一般和非阻塞I/O搭配使用。

一般来说,边缘触发的效率比水平触发的效率要高,因为边缘触发可以减少系统调用次
数。

http://www.jsqmd.com/news/120295/

相关文章:

  • 基于CNN(卷积神经网路)-BiLSTM(双向长短期记忆网络)-Attention(注意力机制)的时间序列预测python代码
  • Vue.js:轻量高效的渐进式前端框架,为何成为开发者首选?
  • EI顶刊复现:基于氨储能技术的电转氨耦合风–光–火综合能源系统双层优化调度附Matlab代码
  • 生成式AI重构内容生态 人机协同定义创作新范式
  • 【课程设计/毕业设计】基于springboot+vue的在线招标系统的设计与实现基于springboot电子招投标系统【附源码、数据库、万字文档】
  • 2025.12.21博客
  • 实用指南:【threejs】材质共享导致的典型问题
  • 2025年儿童鞋服品牌前十名揭晓!哪些品牌靠科技与口碑征服家长? - 品牌测评鉴赏家
  • Vue.js从入门到实战:一站式学习指南
  • 深入解析:NewStar CTF 2025公开赛道-web题目-week4-writeup
  • centos7.9上面卸载中文语言包和中文字体重新安装
  • 深入解析:C#中级43、什么是事件
  • 68
  • 2025年12月男生女生童装书包品牌深度调研报告 - 品牌测评鉴赏家
  • Semantic Kernel使用连接器进行向量搜索
  • Vue.js + Element UI 实战:企业级后台管理系统开发全流程
  • 2025年家长必看!儿童鞋服品牌排行榜前十名权威盘点,这些品牌凭什么征服千万家庭? - 品牌测评鉴赏家
  • 跨境电子商务综合试验区DID(内含七批试验区名单)
  • 0-16岁儿童鞋服品牌全解析:从高端到平价,总有一款适合你家宝贝 - 品牌测评鉴赏家
  • 【漏水定位】基于压力测量和拓扑信息实现的稳健数据驱动漏水定位附Matlab代码
  • 1991-2025年地市级年度科学家数量统计数据
  • 一个基于 .NET MAUI 的开箱即用的 UI 组件库,可快速搭建面向业务的应用程序界面!
  • ESA正式授予Sivers波束成形技术开发合同
  • 2025儿童鞋服品牌Top10揭晓!这些品牌凭什么征服家长? - 品牌测评鉴赏家
  • Ubuntu下Qt应用崩溃自动重启6大方案
  • Java毕设选题推荐:基于springboot的游泳用品专卖店系统的设计与实现泳衣、泳镜、浮板【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 事后诸葛亮分析
  • 宝妈必看!2025高性价比儿童鞋服品牌红榜,安全舒适还省钱 - 品牌测评鉴赏家
  • Java毕设项目推荐-基于Springboot的乡政府管理系统设计与实现基于springboot的村务管理系统的设计与实现【附源码+文档,调试定制服务】
  • 2025年12月男生女生童装鞋子质量评测报告 - 品牌测评鉴赏家