IO 的基本概念

本文详细解析了Java中的I/O模型,包括阻塞IO、非阻塞IO、多路复用IO和异步IO的工作原理。通过生动的借书场景比喻,深入浅出地解释了同步与异步、阻塞与非阻塞的区别。

io 是什么

是以流为基础进行数据的输入输出。通俗点说就是java通过数据流方式和外部进行通讯
I/O中数据的操作是通过流的方式,我们可以把数据流看成水流一样,他可以从一个源头端流入到另一个目的端,且水流不是一次全部到达,而且连续的流入目的端。I是指从外部设备的数据流流入java程序的流。o是指从java程序中把数据流输出到其他设备中的流
IO操作的2个步骤:
1、准备数据
2、把数据从内核中拷贝到程序进程

io的四种模型

阻塞IO、非阻塞IO、多路复用IO、异步IO
首先先了解同步和阻塞的概念
阻塞与非阻塞

主要表现再一个IO操作的过程中,列入读操作时需要准备数据,那么当前IO进程是否等待操作完成,还是得知暂时不能操作后先去做别的事情,一直等待下去,什么事也不做直到完成,这就是阻塞。抽空做些别的事情,只是非阻塞
比较:从CPU角度可以看出非阻塞明显提高了CPU的利用率,进程不会一直在那等待。但是同样也带来了线程切换的增加。增加的 CPU 使用时间能不能补偿系统的切换成本需要好好评估。
示例
  A 小明和小刚两个人都很耿直内向,一天小明来找小刚借书:“小刚啊,你那本XXX借我看看”。 于是小刚就去找书,小明就等着,找了半天找到了,把书给了小明。

B 小明和小刚两个人都很活泼外向,一天小明来找小刚借书:“嘿小刚,你那本XXX借我看看”。 小刚说:“我得找一会”,小明就去打球去了。过会又来,这次书找到了,把书给了小明。

结论:A是阻塞的,B是非阻塞的。

同步与{非同步 ==>异步}

可以看出,判断同步和异步的标准在于:一个IO操作直到完成,是否导致程序进程的阻塞。如果阻塞就是同步的,没有阻塞就是异步的。这里的IO操作指的是真实的IO操作,也就是数据从内核拷贝到系统进程(读)的过程。

继续前面借书的例子,异步借书是这样的:

C 小明很懒,一天小明来找小刚借书:“嘿小刚,你那本XXX借我看看”。 小刚说:“我得找一会”,小明就出去打球了并且让小刚如果找到了就把书拿给他。小刚是个负责任的人,找到了书送到了小明手上。

A和B的借书方式都是同步的,有人要问了B不是非阻塞嘛,怎么还是同步?

前面说了IO操作的2个步骤:准备数据和把数据从内核中拷贝到程序进程。映射到这个例子,书即是准备的数据,小刚是内核,小明是程序进程,小刚把书给小明这是拷贝数据。在B方式中,小刚找书这段时间小明的确是没闲着,该干嘛干嘛,但是小刚找到书把书给小明的这个过程也就是拷贝数据这个步骤,小明还是得乖乖的回来候着小刚把书递手上。所以这里就阻塞了,根据上面的定义,所以是同步。

IO模型

IO 模型可分为以几种
同步阻塞IO (BIO)
同步非阻塞IO(NIO)
IO多路复用
异步IO

  1. 同步阻塞IO blocking I/O 即 BIO
    线程发起一个请求,直到有结果返回,否则则一直阻塞等待,比如我们平常常见的阻塞数据库操作,网络IO等。
    总结:就是程序种就是一直阻塞,而一个IO请求需要一个线程,可想而知当有大量的io请求,线程的创建和销毁,线程间的切换,线程所占用的资源等等要消耗多少时间和资源
  2. 同步非阻塞IO nonBlockin I/O 即 NIO
    非阻塞IO和阻塞IO的最大区别就在与线程发起一个IO请求,不会一直阻塞直到有数据,而是不断的检查是否已有数据,若有数据则读取数据
  3. IO 多路复用
    其实和nio很相似,但是多路复用io要比nio 多一个选择器,即当某个请求需要等待数据返回时,并不是当前这个线程去隔一段时间去轮询一次,而是统一交给一个管理者由这个管理者去管理这个请求是否可以去接收数据了。
    关键部分:
    小明领号后委托给了小a,小a观察到由空位后带回小明:非阻塞,领号后可以安心去做自己的事,不用担心错过
    等待上菜:一直阻塞,直到由菜
    总结:非阻塞IO和阻塞IO的最大区别就在与线程发起一个IO请求,不会一直阻塞直到有数据,而是不断的检查是否已有数据,若有数据则读取数据
<think> 嗯,用户这次想了解IO通信的基本逻辑。从引用内容看,用户可能正在研究网络编程或系统架构,特别是关于异步IO和套接字通信的部分。用户提供的三个引用分别涉及非阻塞IO模型、socket.io使用注意事项和IO虚拟化原理,说明用户有一定技术基础,但需要系统性的概念梳理。 用户的核心问题是“IO通信的基本逻辑”,这需要从操作系统层面解释清楚数据流动的全过程。结合引用[1]提到的异步IO模型和引用[3]的虚拟化原理,应该重点阐述内核空间与用户空间的交互机制。用户似乎对“非阻塞”和“异步”这两个易混淆概念特别关注,这在引用[1]的5-1-2节有提及。 考虑到用户可能实际遇到socket.io通信中断问题(引用[2]),在解释基础逻辑时需要暗示潜在故障点:比如内核缓冲区满导致阻塞,或虚拟化场景下MMIO地址映射错误。不过当前问题更偏向理论,实际操作问题留到后续讨论更合适。 回复结构上,先描述物理层面的硬件交互(磁盘/网卡),再分层说明操作系统抽象层(驱动-内核-用户进程),最后聚焦到异步IO这个高级模型。重点突出数据拷贝次数这个性能关键点,引用[1]提到的“操作系统主动通知”机制正是为了减少轮询开销。 用户没有指定应用场景,但引用[2]显示可能涉及WebSocket,补充TCP连接例子会更贴近实际需求。虚拟化部分虽然引用[3]详细,但基础逻辑解释暂时只需提一句“模拟设备发现流程”即可,避免偏离主线。 </think> IO通信的基本逻辑是计算机系统中**数据在硬件与软件间流动的核心机制**,其核心流程可概括为以下步骤: --- ### **一、IO通信核心逻辑** 1. **请求发起** 应用程序通过系统调用(如`read()`/`write()`)向操作系统发起IO请求(例如读取文件或发送网络数据)。 2. **内核介入** 操作系统内核接管请求: - **设备寻址**:通过总线定位目标设备(磁盘、网卡等)[^3] - **缓冲区管理**:在**内核空间**创建数据缓冲区(避免用户程序直接操作硬件) 3. **数据传输** - **硬件交互**:设备控制器执行物理操作(如磁盘磁头移动、网卡数据包封装) - **数据搬运**:设备控制器通过**DMA(直接内存访问)** 直接将数据写入内核缓冲区(无需CPU参与)[^1] 4. **完成通知** 内核通过以下方式通知应用程序: ```plaintext ┌─────────────┐ ┌─────────────┐ │ 阻塞模型 │←──────┤ 等待数据返回 │ ├─────────────┤ └─────────────┘ │ 非阻塞轮询 │←──────┤ 反复查询状态 │ ├─────────────┤ │ 异步IO │←──────┤ 回调通知结果 │ [^1] └─────────────┘ ``` --- ### **二、关键模型对比** | 模型 | CPU参与度 | 延迟 | 适用场景 | |--------------|-----------|--------|-------------------| | **阻塞IO** | 全程等待 | 高 | 简单低并发 | | **非阻塞IO** | 轮询消耗 | 中 | 中等并发 | | **IO多路复用**| 单线程监控 | 低 | 高并发(select/epoll)| | **异步IO** | 接近零 | 最低 | 高性能服务器 [^1] | > 例如网络通信中,TCP连接通过`socket`抽象为文件描述符,数据流动需经历: > **应用层缓冲区 → 内核Socket缓冲区 → 网卡队列** --- ### **三、技术演进关键点** 1. **虚拟化支持** 虚拟设备需模拟PCI配置空间,使Guest OS能“发现”虚拟硬件并配置IO/MMIO资源[^3] 2. **零拷贝优化** 通过`sendfile()`等系统调用,避免内核与用户空间的数据复制: $$ \text{传统拷贝次数} = 4 \quad \xrightarrow{\text{零拷贝}} \quad 2 $$ 3. **异步框架** Netty等库封装OS异步接口,提供事件驱动模型(如`ChannelFuture`)[^1] --- ### **四、典型问题场景** - **Socket中断**:异步IO回调未正确处理可能导致连接假死[^2] - **虚拟设备故障**:Guest OS配置错误的MMIO地址导致设备不可用[^3] - **缓冲区溢出**:内核Socket缓冲区满时未启用背压机制 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值