I/O发展脉络

news/2024/9/18 20:21:50/文章来源:https://www.cnblogs.com/929code/p/18419260

1. 阻塞 I/O(Blocking I/O)

需求与问题:

  • 早期模型:最早的 I/O 操作模式是阻塞 I/O,即当一个进程或线程执行 I/O 操作时(如读取文件、从网络套接字读取数据),如果数据不可用,进程会被阻塞,无法继续执行其他操作,必须等待 I/O 完成。
  • 问题:由于 I/O 操作(特别是网络 I/O 和磁盘 I/O)速度较慢,线程等待 I/O 完成时会浪费 CPU 资源,且无法执行其他任务,这种模型下无法有效处理并发任务。

场景

  • 单任务系统,每个任务需要等待 I/O 完成后再继续执行其他操作。

技术

  • 最初的 I/O 模型,如 read()write() 系统调用,都是同步阻塞的。

2. 非阻塞 I/O(Non-blocking I/O)

需求与问题:

  • 需求:随着系统中并发任务的增多,不能让进程在等待 I/O 时浪费宝贵的 CPU 资源。希望进程在 I/O 设备未准备好时,能够继续执行其他任务。
  • 非阻塞 I/O:进程发起 I/O 操作时,如果设备不可用,系统调用不会阻塞进程,而是立即返回错误或状态码,告知进程当前未能完成 I/O 操作。进程可以继续执行其他逻辑,并周期性检查 I/O 是否准备好(轮询)。

问题

  • 轮询开销大:尽管进程不会阻塞,但它需要不断地检查 I/O 状态(即轮询),这仍然会浪费大量的 CPU 资源,特别是在高并发场景下,每个进程都需要频繁检查 I/O 状态。

场景

  • 多任务系统,进程需要在等待 I/O 的同时执行其他任务。

技术

  • 通过 fcntl() 设置文件描述符为非阻塞模式,实现非阻塞 I/O。

3. I/O 多路复用(I/O Multiplexing)

需求与问题:

  • 需求:需要一种更高效的方式来处理多个并发的 I/O 操作,不希望线程花费大量时间轮询 I/O 状态,而是让操作系统告诉进程哪些 I/O 操作已经准备好,可以继续执行。
  • 多路复用:通过 select()poll() 或更高效的 epoll() 等系统调用,进程可以将多个 I/O 操作注册到一个“事件监听器”,由操作系统来监控这些 I/O 操作。当某个 I/O 操作准备好(如可读、可写)时,系统调用会返回该事件的描述符,进程才开始处理对应的 I/O。

问题

  • 多路复用大大减少了 CPU 在轮询上的开销,但是进程在处理 I/O 时仍然是同步的,需要调用 read()write() 等函数完成实际的数据传输,I/O 操作本身仍然会阻塞线程。

场景

  • 高并发场景下,一个线程需要监听多个 I/O 操作,而不会阻塞在某个 I/O 上。

技术

  • select()poll()epoll()(Linux)、kqueue()(BSD/Unix 系统)等事件驱动的多路复用技术。

4. 异步 I/O(Asynchronous I/O,AIO)

需求与问题:

  • 需求:非阻塞和多路复用解决了 I/O 等待期间的阻塞问题,但实际的 I/O 操作仍然是同步的,进程仍然需要亲自处理数据传输(如 read()write())。为进一步提升并发效率,需要让 I/O 操作本身也能完全异步。
  • 异步 I/O:异步 I/O 是一种完全非阻塞的 I/O 模式,进程发起 I/O 请求后立即返回,I/O 操作由操作系统在后台完成。当 I/O 操作完成后,操作系统通过回调事件通知来告知进程,进程再处理完成后的数据,而不是自己处理数据传输。

问题

  • 实现异步 I/O 的复杂性较高,不同系统的支持情况不同。在某些场景下,由操作系统处理整个 I/O 操作可能不如应用程序处理高效。

场景

  • 在高并发、高 I/O 需求的场景中,进程希望最大程度地减少对 I/O 操作的等待。

技术

  • AIO(Asynchronous I/O),如 POSIX AIO 提供的 aio_read()aio_write()
  • Windows 中的 I/O 完成端口(IOCP) 是异步 I/O 的典型实现。

5. Reactor 和 Proactor 模式

Reactor 模式

  • Reactor 模式是一种典型的事件驱动模式,结合了非阻塞 I/OI/O 多路复用技术。
  • 进程(或 Reactor)通过 epoll 等机制监听多个 I/O 事件。当 I/O 准备好时,Reactor 通知应用程序处理事件。应用程序调用非阻塞的 read()write() 进行实际的 I/O 操作。
  • 本质:Reactor 模式主要负责通知和调度,I/O 操作由应用程序同步完成。

Proactor 模式

  • Proactor 模式更进一步,结合了异步 I/O。应用程序发起异步 I/O 请求(如异步 read()),操作系统负责完成 I/O 操作,应用程序无需主动读取数据。I/O 完成后,系统通知应用程序,并调用回调函数处理结果。
  • 本质:Proactor 模式不仅负责通知,I/O 操作也是异步的,由操作系统执行。

6. 发展脉络总结

从早期的阻塞 I/O 到现代的异步 I/O,技术的发展是为了提升系统并发处理能力,减少线程等待和阻塞的时间。以下是关键点:

  1. 阻塞 I/O:进程阻塞等待 I/O,效率低下。
  2. 非阻塞 I/O:进程无需阻塞等待,但需要主动轮询 I/O 状态,依然有 CPU 开销。
  3. I/O 多路复用:由操作系统监控多个 I/O 事件,进程只在有事件发生时处理 I/O,减少了不必要的轮询开销。
  4. 异步 I/O:进程发起 I/O 请求后立即返回,操作系统完成 I/O 后通知进程,进程无需参与 I/O 数据传输,进一步减少了等待时间。
  5. Reactor 模式:通过多路复用监听事件,I/O 操作仍由应用程序同步处理。
  6. Proactor 模式:I/O 操作由操作系统完成,应用程序只处理最终结果,完全异步。

总结:

  • 阻塞 I/O非阻塞 I/O:为了避免线程等待,线程可以继续做其他工作。
  • 非阻塞 I/OI/O 多路复用:为了高效处理并发 I/O 任务,减少无效轮询。
  • I/O 多路复用异步 I/O:为了进一步减少进程在 I/O 操作中的参与,最大化并发效率。
  • Reactor 模式Proactor 模式 是基于事件驱动的两种异步设计模式,分别适用于同步非阻塞和异步 I/O 操作场景。

每一步的发展都是为了解决某个特定的并发处理问题,技术的演进是为了更高效地处理越来越多的并发任务。

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

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

相关文章

手脱upx

其实已经是大一下刚开始的事情了,补个档 手动脱壳の新年快乐 查壳,有壳,UPXX32dbg打开文件,查看初始断点点击PUSHAD跟进,CTRL+*设置EIP,开始F8步过,寻找ESP寄存器第一次单个变红的地址此时的内存窗口开始步过第一次步过就发现ESP单个变红,右键跟进内存窗口然后在第一个…

使用firemin降低火狐内存占用

这些年一直使用火狐浏览器,之前一直在AMD平台的机器使用,没有遇到过内存占用过大的问题(可能也与平台无关)。现在在Intel CPU的机器上使用,时间一久,内存就占用很大。试过Firefox/内存消耗严重里面的办法,效果不明显。也试过修改about:config里面的一些选项,也没有达到…

代码随想录算法 - 回溯算法1

题目1 77. 组合 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1: 输入:n = 4, k = 2 输出: [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ]示例 2: 输入:n = 1, k = 1 输出:[[1]]提示:1 <= n <= 20 1 <= k…

错误

PID自己搭的时候,要注意积分模块的位置,搞不明白好久了,原来是我把积分模块的位置放错了。直接用增益模块不容易出错。

OSG开发笔记(三十):OSG加载动力学仿真K模型文件以及测试Demo

前言Osg需要打开模型文件,但是遇到显示动力学仿真的K模型文件,.k文件是一种描述材料属性的文件,比如密度、弹性模量等,该模型文件不是常规中间开放格式,无法直接支持,需要自定义解析并且重建三维模型。 Demo实际非常流程,因为视频转gif导致部分看起来不行:   交互流畅…

0918高数一千题,多元函数积分学

T17.第一型曲线积分空间形式 用斯托克斯公式化成第二型曲面积分 解第二型曲面积分,用高斯公式或者投影转换法,后者注意正负号,上正下负,前正后负 T18.换路径,但是x=1左半段不能化成lnx算 T19.求偏导就对对应字母求就行,不用对y导x T20.多元极值AC-B2>0A>0,极小 A<…

Dynamic Locomotion in the MIT Cheetah 3 Through Convex Model-Predictive Control

1. Swing Leg Control\(J_i \in R^{3*3}\) 是足端雅可比;\(\tau _{i,ff}\) 是前馈力矩 \(\Lambda \in R^{3*3}\)是操作空间惯性矩阵;\(a_{i,ref} \in R^{3*3}\)是机体坐标系下的参考加速度 q是关节角度;\(C_i \dot{q}_i + G_i\)是科里奥利力和重力 2. Ground Force Control …

多机训练时的环境变量

多机训练时的环境变量 通过设置环境变量配置分布式训练,仅仅是为了在交互式 Python 环境下,方便查看实验效果。如果不是学习、试验目的,而是生产需求,可以直接通过 oneflow.distributed.launch 启动分布式训练,该模块内部根据命令行参数,自动设置了必要的环境变量。 1)M…

[Java基础]Stream流

当我第一次阅读 Java8 中的 Stream API 时,说实话,我非常困惑,因为它的名字听起来与 Java I0 框架中的 InputStream 和 OutputStream 非常类似。但是实际上,它们完全是不同的东西。 Java8 Stream 使用的是函数式编程模式,如同它的名字一样,它可以被用来对集合进行链状流式…

学习高校课程-软件工程-软件工程(ch2)

DEFINING THE DISCIPLINE THE SOFTWARE PROCESS General Principles2.1 DEFINING THE DISCIPLINE definition for software engineering 软件工程的定义 (1) The application of a systematic, disciplined, quantifiable approach to the development, operation, and mainten…

反汇编分析赋值与自增自减

目录++(--)后置的++(--)真的是先使用,后自增吗?后置++和前置++的差别复杂表达式++i+++i+++i贪心法编译器的贪心规则不是保证一定正确的规则赋值的原理 ++(--)后置的++(--)真的是先使用,后自增吗?概念:前置++是先自增,后使用; 后置++是先使用,后自增. 下面从汇编角度看后置++的…