五种I/O模型

180 阅读4分钟

五种I/O模型

1、I/O基本理解

I/O,即为输入/输出(Input / Output),在网络环境下,I/O主要分为两步:等 + 数据迁移

  1. 所谓的等,就是内核等待I/O设备准备好数据

  2. 数据迁移,就是内核将数据从内核空间拷贝到用户空间

    如果想要提高I/O的速度,主要就是将等的时间降低

    在UNIX中,I/O分为五种模型:同步阻塞I/O、同步非阻塞I/O、I/O多路复用、信号驱动I/O和异步I/O

前四种都属于同步I/O

2、同步阻塞I/O

同步阻塞I/O模型中,应用程序发起read调用后,会一直阻塞,直到内核把数据拷贝到用户空间。这就类似与烧开水泡面,一直等水烧开了,才撕开泡面袋,再冲开水等一系列操作,在等待水烧开之前是不做任何事情的

3、同步非阻塞I/O

同步非阻塞I/O模型中,应用程序会一直发起read调用(轮询),等待数据从内核空间拷贝到用户空间的这段时间里,线程依然是阻塞的,直到在内核把数据拷贝到用户空间。 这就好比你觉得泡面烧开水的时候一直傻站着等它烧开,太浪费时间了,在此期间可以去切切香肠、煎煎蛋什么的,但是会是不是探头去留意水是否烧开,这个探头的动作就是轮询

但是这种轮询过程是十分耗费CPU资源的,就像是一直探头,探多了,头也累。

4、I/O多路复用

I/O多路复用模型中,线程首先发起select调用,轮询内核数据是否准备就绪,等内核把数据准备好了,用户线程再发起read调用。read调用的过程还是阻塞的。 这个I/O模型就好比你烧了好几壶水,你不再只为一壶水而等待,你仍然需要等待水的烧开,但与之前相比,你等待的不只是一壶水,而是很多壶水。

IO多路复用是多了一个select函数,select函数有一个参数是文件描述符集合,对这些文件描述符进行循环监听,当某个文件描述符就绪时,就对这个文件描述符进行处理。

其中,select只负责等,recvfrom只负责拷贝。 IO多路复用是属于阻塞IO,但可以对多个文件描述符进行阻塞监听,所以效率较阻塞IO的高

5、信号驱动I/O

信号驱动IO模型中,应用进程告诉内核:当数据报准备好的时候,给我发送一个信号,对SIGIO信号进行捕捉,并且调用我的信号处理函数来获取数据报。 好比于你烧水的时候,又想去做其它事情又怕水烧开了不知道,因此在开水壶上设置了一个装置,当水烧开的时候就能够第一时间通知你。

6、异步I/O

异步I/O模型中,异步I/O是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知响应的进程进行后续的操作。就是当你烧水的时候,你让你女朋友来帮你看,当水开了的时候立马通知你,然后进行下一步处理。

7、I/O模型之间的对比

阻塞程度:同步阻塞I/O > 同步非阻塞I/O > I/O多路复用 > 信号驱动I/O > 异步I/O

效率是反过来的

8、Java中常见的I/O

Java中常见的I/O模型有三种:BIO、NIO、AIO

8.1BIO(Blocking I/O)

BIO属于同步阻塞IO

8.2NIO(Non-blocking/New IO)

Java中的NIO于Java1.4中引入,对应Java.nio包。提供了Channel,Selector,Buffer等抽象。NIO中的N可以理解为Non-blocking,不单纯是New。它支持面向缓冲的,基于通道的I/O操作方法,对于高负载、高并发应用可以使用。

Java中的NIO对于的是I/O多路复用模型

8.3AIO(Asynchronous I/O)

AIO属于异步IO模型