首页/新闻资讯/正文详情

Linux中的高级IO

发布时间:2026/9/24 17:53:49 来源:云帆数科 栏目:资讯中心
Linux中的高级IO
目录一、五种IO基本模型二、select三、poll四、epoll一、五种IO基本模型IO的本质等待数据就绪 将数据从内核拷贝到用户空间1. 阻塞IO在内核数据准备好之前系统调用一直处于等待状态所有套接字默认都是阻塞方式2. 非阻塞IO当内核数据没有准备好的时候系统调用仍然会返回并且返回EWOULDBOLCK[是EAGAIN的别名]非阻塞IO需要不断访问文件描述符这个过程成为轮询对于CPU资源的消耗较大只有特定场景下使用3. 信号驱动式IO当内核数据准备好的时候使用SIGIO信号通知应用程序进行IO操作4. IO多路转接与阻塞IO方式类似但最大的区别在IO多路转接可以同时监听多个文件描述符5. 异步IO当内核将数据拷贝完成后通知应用程序IO中的小点:1.同步IO vs 异步IO同步IO当发起一个调用的时候在没有得到返回结果之前不会得到返回值只有当得到返回值的时候才会得到返回结果调用者主动等待结果异步IO与同步IO相反当发起一个调用的时候会立刻得到返回值但是不会得到返回结果而是被调用着通过状态或者回调函数来通知调用者2.阻塞IO vs 非阻塞IO阻塞或IO在没有拿到返回结果之前该线程会被挂起非组设IO不能立刻拿到返回结果的时候该线程不会被挂起3. 如何通用设置非阻塞IO二、selectselect是系统提供实现多路复用输入/输出的接口select系统调用会同时监听多个文件描述符的状态变化在监听的时候默认处于等待状态只有当一个或多个文件描述符就绪的时候才会返回1.接口int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds , struct timeval *timeout);2.参数参数nfds是需要监视的最⼤的⽂件描述符值1rdset,wrset,exset分别对应于需要检测的可读⽂件描述符的集合可写⽂件描述符的集 合及异常⽂件描述符的集合;参数timeout为结构timeval⽤来设置select()的等待时间NULL: 则表示select ()没有timeout, select将一直被阻塞 直到某个文件描述符上发生了事件0:仅检测描述符集合的状态然后立即返回 并不等待外部事件的发生。特定的时间值如果在指定的时间段里没有事件发生 select将超时返回。3.返回值执⾏成功则返回⽂件描述词状态已改变的个数如果返回0代表在描述词状态改变前已超过timeout时间没有返回当有错误发⽣时则返回-1错误原因存于errno此时参数readfdswritefds, exceptfds和 timeout的值变成不可预测。4.select特点fd_set中的每一个比特位对应一个文件描述符除此之外还需要一个数组来存储监控的文件描述符因为每次返回之后都会把之前加入但是为响应的文件描述符清空同时这个数组还需要用来判断文件描述符的就绪转态5.select缺点用户每次使用的时候都需要手动设置fd,使用并不方便每次调用接口的时候都需要将fd从用户态拷贝到内核态同时在内核中也需要遍历fd_set数组当fd数量较大的时候开销很大除此之外select支持的文件描述符数量太少三、poll1.接口int poll(struct pollfd *fds, nfds_t nfds, int timeout);2.参数fds是一个poll函数监听的结构列表.每一个元素中,包含了三部分内容:文件描述符,监听的事件集合,返回的事件集合.nfds表示fds数组的长度.timeout表示poll函数的超时时间,单位是毫秒(ms).3.返回值返回值小于0,表示出错;返回值等于0,表示poll函数等待超时;返回值大于0,表示poll由于监听的文件描述符就绪而返回.4.特点pollfd结构包含了要监视的event和发生的event不再使用select“参数-值”传递的方式.接口使用比select更方便.poll没有最大数量的限制5.缺点和select函一样poll返回后需要循环遍历pollfd数组每次调用poll都需要把大量的pollfd结构从用户态拷贝到内核中.同时连接的大量客户端在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长,其效率也会线性下降.四、epoll1.接口//创建epoll模型 int epoll_create(int size); //添加/修改/删除监听的文件描述符 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); //监听fd int epoll_wait(int epfd, struct epoll_event *events,int maxevents , int timeout);2.参数epoll_create:自从linux2.6.8之后size参数是被忽略的,用完之后,必须调用close()关闭.epoll_ctl:epfd是epoll_create()的返回值(epoll的句柄).op表示动作用三个宏来表示.[EPOLL_CTL_ADD,EPOLL_CTL_MOD,EPOLL_CTL_DEL]fd是需要监听的fd.event是告诉内核需要监听什么事.epoll_wait:events是分配好的epoll_event结构体数组,epoll将会把发生的事件赋值到events数组中(events不可以是空指针内核只负责把数据复制到这个events数组中不会去帮助我们在用户态中分配内存).maxevents告诉内核,events的最大容量参数timeout是超时时间(毫秒0会立即返回-1是永久阻塞)3.返回值如果函数调用成功返回对应I/O上已准备好的文件描述符数目返回0表示已超时,返回小于0表示函数失败.4.工作原理当我们使用epoll_create()时候内核会创建一个evenloop结构体对象其中包含一个红黑树当我们调用epoll_ctl()的时候内核会将该文件描述符对应的节点注册到红黑树上并将节点与网卡驱动程序做绑定此外还有一个双向链表用来记录已经就绪的文件描述符对应的节点当有事件到来的时候网卡驱动程序触发中断将就绪文件描述符对应的节点加入到双向链表中5.优点1.epoll能够监听的文件描述符是没有上限的2.epoll提供三个接口函数给用户并没有使操作更加复杂通过epoll_ctl()我们只有在注册事件的时候才会放生从用户态到内核态的数据拷贝增加了资源利用的效率3.同过双向链表我们可以实现O(1)的获取已经就绪的文件描述符极大提高了效率6.工作模式1.LT模式(level trigger)当epoll检测到socket上事件就绪的时候我们可以不进行处理或处理一部分当第二次epoll_wati()的时候仍然会立刻返回并通知socekt事件就绪2.ET模式(edge trigger)当epoll检测到socket上事件就绪的时候我们必须一次性将数据处理完因为当第二次epoll_wait()的时候如果没有新数据的到来并不会返回上次没有处理完数据对应的文件描述符7.ET与非阻塞ET模式使用的时候对应的应该将对应的文件描述符设置为非阻塞并不是接口上的要求而是工程实践上的需求假如存在一种场景客户端只有接受到服务端响应的时候才会发送第二次请求服务端这边只有在读到10k数据的时候才会向客户端发送响应这时候我们如果使用阻塞模式读的话如果只读到1k数据那么后续epoll_wait()并不再回返回这次通信的文件描述符就会导致通信错误8.惊群现象与解决方法惊群现象多个 worker 进程线程各自持有独立 epoll同时注册同一个 listen 监听 fd。当有新 TCP 连接到达listen socket 变为就绪内核唤醒多个阻塞于 epoll_wait 的 worker随后多个 worker 调用 accept但只能有一个 accept 成功其余 accept 返回 EAGAIN这些进程白白被唤醒发生不必要的上下文切换造成 CPU 损耗解决方法1.多线程单独一个线程负责 accept分发连接给工作线程2.多进程2.1.lighttpd 放任惊群多个 worker 被唤醒accept 遇到 EAGAIN 之后退回 epoll_wait但是仍然存在进程调度开销2.2.nginx accept‑mutex使用共享内存上的进程间互斥锁非阻塞 trylock 抢锁抢到锁的 worker 才监听 listen_fd同时依靠 ngx_accept_disabled 做负载控制同一时刻只有一个 worker 监听 listen消除惊群2.3.Linux4.5 之后注册 listen fd 时带上EPOLLEXCLUSIVE标记内核保证就绪时仅唤醒一个 worker在内核层面解决惊群。

相关推荐

时间轮设计和正则表达式使用方法
时间轮设计和正则表达式使用方法

个人主页:小则又沐风 个人专栏: • [数据结构] • [竞赛专栏] • [C语言] • [C] • [Linux] • [OJ项目] • [MySQL] •[GIT] 时间轮 1.什么是时间轮 我们先不来讲解什么是时间轮,我们先来讲解一下我们在写代码的时候我们可能遇到的问题。… · 2026/9/24 17:53:49

12.常见的transforms(一)
12.常见的transforms(一)

输入类型:重点关注三种输入格式: PIL格式:使用Image.open()读取 Tensor格式:使用ToTensor()转换 numpy数组:使用cv.imread()读取 输出类型:不同Transform的输出格式可能不同,需要特别注意 作用&… · 2026/9/24 17:53:49

【 ‌infrastructure】【数据中心】【AI infra】第十篇 智能计算数据中心解决方案集成测试和交付知识体系1004
【 ‌infrastructure】【数据中心】【AI infra】第十篇 智能计算数据中心解决方案集成测试和交付知识体系1004

1108|OCS + 空芯光纤(HCF)超低延迟 Rail:MEMS/WSS 光路切换、HCF 模式不稳定性、RoCE 无损与 K8s 弹性再调度 工程内容(OSI L1–L7+K8s) L1:空芯光纤(HCF)链路(典型 1550 nm,反谐振/光子带隙结构,传播速度 ~0.999c,衰减 ~0.5–2 dB/km,支持多模/少模);OCS 核… · 2026/9/24 17:53:49

Chroma Lexer 测试体系解析:从 `*.actual`/`*.expected` 配对到 RECORD 回归生成
Chroma Lexer 测试体系解析:从 `*.actual`/`*.expected` 配对到 RECORD 回归生成

Chroma Lexer 测试体系解析:从 *.actual/*.expected 配对到 RECORD 回归生成 【免费下载链接】sliver Adversary Emulation Framework 项目地址: https://gitcode.com/gh_mirrors/sl/sliver 导读 Chroma 是 Go 生态中广泛使用的通用语法高亮库,它… · 2026/9/24 18:32:59

用Git管理Obsidian笔记库:从零搭建版本控制与多设备同步方案
用Git管理Obsidian笔记库:从零搭建版本控制与多设备同步方案

用Git管理Obsidian笔记库这件事,我认真想推荐给每一个笔记重度用户。很多人一听到“版本控制”“提交推送”就头皮发麻,觉得这是程序员才需要的东西,但Obsidian Git这套组合真正上手之后,你会发现它把“笔记永远不丢、随时可以找回… · 2026/9/24 18:32:46

自助购药小程序源码解析:Java后端与微信前端实战指南
自助购药小程序源码解析:Java后端与微信前端实战指南

简介:这是一份基于Java与SSM框架开发的自助购药小程序完整源码,面向毕业设计、课程设计及小程序Java全栈学习者,覆盖用户端、商家端与后台管理端,可解决从药品展示、下单支付到发票管理等全流程设计问题。压缩包共1319个文件&… · 2026/9/24 18:32:46

用Git管理Obsidian笔记库:实现版本控制与多设备同步的完整指南
用Git管理Obsidian笔记库:实现版本控制与多设备同步的完整指南

前阵子我电脑系统盘突然报错,我一边重装一边冒冷汗:存在 Obsidian 里的几年笔记,万一没了我真的会崩溃。好在当时我已经把笔记库用 Git 管了起来,重装系统后拉下仓库,一条笔记都没少。那一刻我就想说,这套 … · 2026/9/24 18:32:46

三维点云车辆检测中的注意力机制与PointNet++工程实践
三维点云车辆检测中的注意力机制与PointNet++工程实践

简介:面向自动驾驶、机器人导航等点云感知场景,提供一份基于Python的三维点云车辆目标检测算法实现,核心亮点是在点级特征增强与多尺度特征聚合中引入注意力机制,使模型有效聚焦关键结构信息,提升检测精度。压缩包共34… · 2026/9/24 18:32:46

Windows下用WSL2 + Ubuntu + Cursor搭建Linux开发环境全指南
Windows下用WSL2 + Ubuntu + Cursor搭建Linux开发环境全指南

如果你手里有一个必须在 Ubuntu 下才能跑起来的项目,又不想折腾双系统,或者被虚拟机卡到怀疑人生,那么 WSL 基本是 Windows 上最舒服的一条路。最近我把手头的 Python 数据处理、PyTorch 训练脚本和嵌入式交叉编译工程都迁到了 WSL 里的 Ubun… · 2026/9/24 18:32:46

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码