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

文件I/O与I/O多路复用

1.文件表

进程打开一个文件,会与三个表发生关联,分别是:文件描述符表、文件表、索引结点表。
在这里插入图片描述

在 Linux/Unix 系统中,Socket 确实被抽象为一种特殊的文件。这是 Unix “一切皆文件”(Everything is a File)设计哲学的体现。

在 /proc/pid/fd/ 中可见。

为什么fork之后,要把不用的文件关掉
防止资源泄漏,每个打开的文件描述符都会占用系统资源。系统对单个进程和整个系统能打开的文件描述符数量都有限制。

C 标准库(stdio)中 fread 和 fwrite 的缓冲机制。这是理解高性能 I/O 操作的关键之一。
一、为什么需要缓冲?
核心目的:减少系统调用的次数,极大提升 I/O 效率。

stdin 和 stdout 如果指向终端(交互式设备),通常是行缓冲;如果被重定向到文件,则通常变为全缓冲。

2.多路复用

1.select 的作用

1.select 的核心作用是:允许一个进程(或线程)同时监视多个文件描述符(File Descriptor, FD),等待其中一个或多个 FD 变得“可读”、“可写”或“发生异常”,然后通知程序进行相应的读写操作。

简单来说,它解决了“一个服务端程序如何同时高效地处理多个客户端连接”的问题,而不需要为每个连接都创建一个进程或线程。

2.为什么要用 select?—— 解决的核心问题
在 select/poll/epoll 这类技术出现之前,处理多个网络连接的常规方法是:

多进程模型:accept 一个连接就 fork 一个子进程来处理。问题:进程创建、销毁、上下文切换开销巨大,资源占用高,难以应对成千上万的连接(这就是著名的 C10K problem)。
多线程模型:accept 一个连接就创建一个线程。问题:虽然比进程轻量,但大量线程的上下文切换开销依然很大,而且编程中线程同步非常复杂。
非阻塞忙轮询(Busy-polling):将 socket 设为非阻塞,然后在一个循环里依次调用 recv 检查每个连接。问题:CPU 资源被极大浪费,因为大部分时间都是在做无用的检查。
select 的出现就是为了克服上述模型的缺点:

资源高效:一个线程就能管理成百上千个网络连接,大大降低了系统资源消耗。
避免忙等待:在没有事件发生时,select 会阻塞(睡眠),让出 CPU 资源。只有当事件发生(或有信号中断)时,它才会被唤醒,从而高效利用 CPU。
统一事件管理:可以同时等待多种类型的 I/O 事件(可读、可写、异常),使得程序能够统一处理所有连接的 I/O 活动。

3.核心步骤对应代码
设置集合:FD_ZERO, FD_SET 初始化并填充需要监视的 fd(如监听 socket 和所有客户端 socket)。
阻塞等待:调用 select(nfds, &readfds, NULL, NULL, NULL)。
检查结果:select 返回后,使用 FD_ISSET 遍历所有 fd,判断哪些 fd 上有事件发生。
处理事件:
如果是监听 socket 可读,说明有新连接,调用 accept。
如果是客户端 socket 可读,说明有数据到来,调用 recv。

2.poll 相对于select的真正优势

既然都需要轮询,那 poll 的优势在哪里?它解决的是 select 的其他设计缺陷:

问题 select poll
连接数限制 有,受 FD_SETSIZE (通常1024) 限制 无硬性限制,仅受系统内存限制
内核反馈机制 使用“传入-传出”参数,每次调用后原始集合被破坏,需要重置。 使用独立的 events(输入)和revents(输出)字段,无需重置。
处理异常 需要额外的 exceptfds 集合。 可以通过 events 字段直接设置

3.epoll

解决了这个轮询问题,epoll 的工作方式是“事件就绪通知”:

你告诉内核要监视哪些 FD(通过 epoll_ctl)。
当事件就绪时,epoll_wait 调用返回,它只给你一个装满就绪事件的数组,这个数组的大小恰好就是就绪 FD 的数量。
你直接处理这个数组即可,时间复杂度是 O(就绪的fd数量),而不是 O(总共监视的fd数量)。

epoll_create1: 创建一个 epoll 实例,返回一个文件描述符(epfd),用于管理所有待监视的 FD。
epoll_ctl: 向 epoll 实例(epfd)添加、修改或删除要监视的 FD 及其感兴趣的事件(EPOLLIN, EPOLLOUT 等)。这个操作只需执行一次,而不是每次循环都传递整个集合。
epoll_wait: 等待事件发生。它只返回那些已经就绪的 FD 信息(一个 events 数组),数量就是就绪的 FD 数。应用程序无需遍历所有监视的 FD,直接处理这些就绪的事件即可。这是 O(1) 的复杂度。


文章转载自:

http://cDY8Spaa.bpmfr.cn
http://OsBfHQHK.bpmfr.cn
http://d11n2MQj.bpmfr.cn
http://jjN4H03M.bpmfr.cn
http://CRFgIpKC.bpmfr.cn
http://VvdjixSm.bpmfr.cn
http://tffZUJN4.bpmfr.cn
http://sg5v4s0P.bpmfr.cn
http://YyX0EFLM.bpmfr.cn
http://zV6mDRuA.bpmfr.cn
http://T8RjZ9Rn.bpmfr.cn
http://OXnliPaH.bpmfr.cn
http://mQDWVouz.bpmfr.cn
http://VEnMHUVD.bpmfr.cn
http://GasRahAk.bpmfr.cn
http://4BckqZpS.bpmfr.cn
http://UONnqKux.bpmfr.cn
http://G0JvBYWq.bpmfr.cn
http://u65u2Z9t.bpmfr.cn
http://6WFRiSj6.bpmfr.cn
http://kni0KTjq.bpmfr.cn
http://5icWtKXc.bpmfr.cn
http://jTCMyonn.bpmfr.cn
http://pgUP2rea.bpmfr.cn
http://ehwhqoiR.bpmfr.cn
http://3tpAZqD2.bpmfr.cn
http://PSoQahcA.bpmfr.cn
http://aVSqiJsx.bpmfr.cn
http://nAEbkYsW.bpmfr.cn
http://54RyJfBG.bpmfr.cn
http://www.dtcms.com/a/370453.html

相关文章:

  • protobuf的序列反序列化
  • Linux/UNIX系统编程手册笔记:共享库、进程间通信、管道和FIFO、内存映射以及虚拟内存操作
  • 吴恩达机器学习(九)
  • 基于多级特征编码器用于声学信号故障检测模型
  • 【LeetCode热题100道笔记】二叉树中的最大路径和
  • The Open Group 宣布成立Industrial Advanced Nuclear™ 联盟)
  • 问题:指令译码前控制信号还没有产生,那么如何控制译码前指令的动作呢?
  • 软件测试理论
  • Wisdom SSH 是一款创新性工具,通过集成 AI 助手,为服务器性能优化带来极大便利。
  • ChatGPT下的相关聊天提示词
  • C# WinForm分页控件实现与使用详解
  • 在Ubuntu平台搭建RTMP直播服务器使用SRS简要指南
  • 设计艺术~缓存结构设计
  • 腾讯混元游戏视觉生成平台正式发布2.0版本
  • MySQL整理【01】
  • MQTT 与 Java 框架集成:Spring Boot 实战(三)
  • docker 推送仓库(含搭建、代理等)
  • 了解Python
  • LeetCode //C - 848. Shifting Letters
  • 数学判官为中医续命
  • 华为OmniPlacement技术深度解析:突破超大规模MoE模型推理瓶颈的创新设计
  • Web Worker 从原理到实战 —— 把耗时工作搬到后台线程,避免页面卡顿
  • [网络入侵AI检测] docs | 任务二分类与多分类
  • Browser Use:打造你的浏览器自动化助手
  • 全维度质量保障:捷多邦厚铜板控制方法详解
  • PDF文件基础-计算机字体
  • Python 制作的一个小说在线阅读工具
  • 携程社招前端面经
  • 基于扰动观察法(PO)的光伏最大跟踪策略Simulink
  • 提示语规则引擎:spring-ai整合liteflow