常见的IO模型有四种:

  1. 同步阻塞IO(BIO)
  2. 同步非阻塞IO(NIO)
  3. 异步非阻塞IO(AIO)
  4. IO多路复用
首先先要明白阻塞、非阻塞、同步、异步的概念:

        阻塞和非阻塞是一组相对应的概念,其强调的是等待响应结果的状态方式,是一直就在等待什么都不可以做(阻塞),还是在等待的时候可以做其他事情(非阻塞),多是有连接有请求处理时等待结果的状态方式。

        同步和异步强调的是获取IO结果的方式,同步需要时刻关心IO结果(轮询);异步则是不需要主动关心结果,在IO完成时会收到相应的通知(事件驱动)。同步和异步强调的时对IO结果的获取方式。


一、同步阻塞IO(BIO)


这是最常见、最简单的一种IO模型,用户线程在内核进行IO操作时被阻塞,直到系统调用完成。

应该注意到,在阻塞的过程中,其他程序还可以执行,因此阻塞不意味着整个操作系统都被阻塞。因为其他程序还可以执行,因此不消耗 CPU 时间,这种模型的执行效率会比较高,但对CPU的资源利用率不足。

二、同步非阻塞IO(NIO)

非阻塞意味着用户程序发起请求在执行系统调用后还可以继续做其他的事情,内核并不是马上执行完 I/O,而是以一个错误码来告知用户程序 I/O 还未完成。为了获得 I/O 完成事件,用户程序必须调用多次系统调用去询问内核,甚至是忙等,也就是在一个循环里面一直询问并等待。

由于 CPU 要处理更多的用户程序的询问,因此这种模型的效率是比较低的。

请求的过程中,虽然用户线程发起IO请求后就可以立即返回,没有阻塞,但为了得到响应数据,它需要不断的轮询,不断的消耗CPU资源,所以同步非阻塞IO效率时比较低的,一般很少直接使用这种模型,而是在其他IO模型红使用非阻塞IO这一特性。

三、异步非阻塞IO(AIO)

该模式下,I/O 操作会立即返回,之后可以处理其它操作,并且在 I/O 完成时会收到一个通知,此时会中断正在处理的操作,然后继续之前的操作。异步非阻塞IO需要操作系统强大的支持,也比较复杂。


四、IO多路复用

            IO多路复用:多路网络连接复用一个IO线程。指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程。它与上面的三个模型不是相对立的,它更像是一种机制,还可以配合某些模型公用。

            常见的IO多路复用的机制有select、poll、epoll。:。

            Redis、Nginx底层实现原理都用到了IO多路复用机制,保证高并发的情况。


附:通俗理解NIO、BIO、AIO

        假设有这么一个场景,有一排水壶(客户)在烧水。
          AIO的做法是,每个水壶上装一个开关,当水开了以后会提醒对应的线程去处理。
          NIO的做法是,叫一个线程不停的循环观察每一个水壶,根据每个水壶当前的状态去处理。
          BIO的做法是,叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。