在Android开发中,不可避免的会接触到IO,抛开体系部分的IO,在运用开发领域,仍然会接触到IO,诸如:
- 文件读写
- 网络通信
或许您在开发中不再直接运用JDK中的API完结IO部分的功能,但仍有必要了解相关常识。
JAVA的IO,经过虚拟机建立在操作体系的IO之上,在整理JAVA的IO时,可适当了解操作体系部分IO的相关常识,但本系列不会深究。
纲要
本系列中,方案包括以下内容:
- JAVA 经典IO 一篇
- JAVA NIO 1-3篇
- OK-IO 1篇
- Linux体系中的IO(如有必要)
- IO模型概览 本文顺带
下图体现了一个冯诺依曼机的结构:
在操作体系中,IO操作会涉及到 用户空间、内核空间的切换
,以及 内核空间、用户空间之间的数据拷贝
,接下来就常见的IO模型,简单了解下概念和规划理念。
注:不同操作体系在完结时会存在一定差异,不做深究
IO模型
- 堵塞I/O(blocking I/O)
- 非堵塞I/O(non-blocking I/O)
- I/O复用(I/O multiplexing)
- 信号驱动式I/O(signal-driven I/O)
- 异步I/O(asynchronous I/O)
堵塞I/O(blocking I/O)
堵塞IO、BIO、Blocking IO
在
内核IO操作
彻底完结后,才回来用户空间
履行运用的操作。此过程中,用户空间程序的履行状况是堵塞的,程序需等到IO操作彻底完结。
以读为例,示意图如下
非堵塞I/O(non-blocking I/O)
留意,此处不要与 JAVA的nio包
内容混杂
非堵塞IO
比较于BIO,NIO中
数据等待阶段
是非堵塞的,操作体系不会挂起运用。类似于JAVA中运用Future进行非堵塞多线程编程,以读为例,运用
轮询
内核,数据是否完结,数据预备安排妥当后,建议体系调用获取数据,体系调用的过程中,运用堵塞。
轮询: 运用进程对非堵塞描述符循环发送体系调用,以查看某个操作是否安排妥当
以读为例,示意图如下
I/O复用(I/O multiplexing)
I/O复用
经典的Reactor规划。进程经过将一个或许多个操作堵塞在
select
阶段,select能够帮我们检测fd(文件操作符)
是否处于安排妥当状况。如果有数据预备好,就回来可操作的信息,再进跋涉一步地读写操作
当需要观测的fd很多时,数据预备的占比可能变高,轮询的收益会降低,而多路复用会得到更高的收益。
以读为例,示意图如下
信号驱动式I/O(signal-driven I/O)
信号驱动式I/O
在数据预备阶段,不再堵塞等待,内核预备好数据后,经过信号告诉用户空间,用户空间的运用建议体系调用,堵塞获取数据
以读为例,示意图如下
异步I/O(asynchronous I/O)
异步I/O
不同于信号驱动式I/O,在数据等待完结后,进行内核到用户空间的数据拷贝,完结后信号告诉运用程序处理数据