一、什么是IO?
对于磁盘IO,将数据从磁盘中读取数据到内存空间为输入
input,相反地将数据从内存空间写入磁盘就是输出output
何为IO?简单而言就是输入输出,I/O=input/output。对计算机而言,IO是计算机核心与其他设备间数据迁移的过程。
二、IO基础概念
🌟 同步与异步
同步和异步是针对应用程序和内核的交互而言的
- 同步:用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪。即A调用B,B在处理完之前不会通知A,只有等待处理完之后才会通知A
- 异步:用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知。即A调用B,B在接到请求后先告诉A我已经接到请求了,然后异步去处理,处理完之后通过回调等方式再通知A
- 判断窍门:是否需要马上返回结果
🌟 阻塞与非阻塞
阻塞与非阻塞是针对用户就和内核空间IO操作的方式而言的
- 阻塞:用户空间通过系统调用和内核空间发送IO操作时,该调用是堵塞的需要等待的。即A调用B,A需要一直等着B的返回,期间不能进行其他操作
- 非阻塞:用户空间通过系统调用和内核空间发送IO操作时,该调用是不堵塞的,直接返回的,只是返回时,可能没有数据而已。即A调用B,A无需一直等着B的返回,可以进行其他操作
- 判断窍门:是否需要一直等待
🌟 用户空间以及内核空间
在Linux中,虚拟内存被操作系统划分为两块:内核空间和用户空间,内核空间是操作系统内核访问的内存区域,是受保护的内存空间,用户空间是用户应用程序访问的内存区域。处于安全方面的考虑,这两块的内存区域是相互隔离的,用户空间的崩溃不会影响到内核空间。
用户空间不能直接调用系统资源,可以通过系统调用(system call)向内核发起请求,调用系统资源(通过系统调用,可以从用户空间切换到内核空间)
🌟 IO的分类
IO可以分为内存IO、网络IO、磁盘IO,我们通常的IO指后两种。
I/O按照设备来分可以分为两种:一种是网络IO,也就是通过网络进行数据的拉取和输出;另一种是磁盘IO,主要是对磁盘进行读写工作。
磁盘IO以及网络IO之间的对比:
磁盘IO的主要延迟=机械转动延时+寻址延时+块传输延时
网络IO的主要延迟=服务器响应+带宽限制+网络延时+跳转路由延时+本地接收延时
🌟 一次IO操作的过程
应用程序的一次IO操作主要可以分为两个阶段:
- IO调用:应用程序进程向操作系统内核发起调用
- IO执行:操作系统内核完成IO操作
IO调用由进程发起(用户态),IO执行是系统内核的工作(内核态)
操作系统内核完成IO包括两个阶段:
- 数据准备:内核等待IO设备准备好数据
- 数据拷贝:将数据从内核缓冲区拷贝到用户进程缓冲区
三、IO模型
同步阻塞IO:
Blocking IO,传统IO模型
同步非阻塞IO:
Non-blocking IO,默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK
IO多路复用:
IO Multiplexing,并发式同步阻塞IO,使用Reactor设计模式,例如Java中的Selector、Linux中的epoll
异步IO:
Aysnchronous IO,异步非阻塞IO,使用Proactor设计模式
(1)同步阻塞IO模型
用户空间的进程发起IO系统调用后,会导致进程被阻塞,转到内核空间处理,直到数据准备好,并将数据从内核复制到用户进程,整个IO处理完毕后才返回成功提示。这个过程,整个进程被阻塞,不能处理其他IO。
使用场景:阻塞Socket、Java BIO
调用应用程序处于一种不再消费CPU而只是简单等待相应的状态;如果内核数据一直没准备好,用户进程将会一直阻塞
(2)同步非阻塞IO模型
用户空间的进程发起IO系统调用后,内核会立马返回结果给进程,如果内核数据准备好,返回数据,否则返回一个错误信息,用户进程不会一直被阻塞,而是通过轮询的方式再次进行请求,直到数据准备好,在将内核数据拷贝到用进程。(拷贝数据的过程仍是阻塞的)
相对于阻塞IO,虽然大幅提升了性能,但是它依然存在性能问题,即频繁的轮询,导致频繁的系统调用,同样会消耗大量的CPU资源
(3)IO多路复用模型
IO多路复用,系统为我们提供一类函数,可以监听多个fd操作,任何一个返回内核数据就绪,应用进程再发起系统调用获取数据,Linux中IO复用的实现方式有select、poll、epoll
select:
(4)信号驱动模型
当进程发起一个IO操作,不会主动询问确认数据是否就绪,而是会向内核发送一个信号,然后进程可以去做别的事情,不会导致阻塞;当内核数据就绪时会发送一个信号通知用户进程,进程收到信号便调用系统调用读取数据。
信号驱动模型,数据准备好通知进程读取数据时,数据复制仍是阻塞的,除此之外,Linux中信号队列是有限制的,超过限制就无法读取数据。
(5)异步IO模型
AIO实现IO全流程非阻塞,当进程发起一个IO操作,进程不阻塞,但也不会立即返回数据结果。内核把整个IO处理完后,会发送信号通知用户进程结果,如果IO操作成功则用户进程直接获取到数据。
四、小结
| 同/异步 | 阻塞 | 非阻塞 |
|---|---|---|
| 同步 | 阻塞IO/IO多路复用 | 非阻塞IO/信号驱动IO |
| 异步 | xxx | 异步IO |
阻塞IO、非阻塞IO、IO多路复用、信号驱动IO本质上都是同步的IO模型