【Java 五种IO模型】


在这里插入图片描述

在学习五种IO模型之前,我们要先清楚以下概念:

  • 阻塞:
    当某个事件或者任务在执行过程中,它发出一个请求操作,但是由于该请求操作需要的条件不满足,那么就会一直在那等待,直至条件满足。

  • 非阻塞:
    当某个事件或者任务在执行过程中,它发出一个请求操作,如果该请求操作需要的条件不满足,会立即返回一个标志信息告知条件不满足,不会一直在那等待。

  • 同步:
    如果有多个任务或者事件要发生(主要指 IO 事件),这些任务或者事件必须逐个地进行并且必须应用程序参与,一个事件或者任务的执行会导致整个流程的暂时等待,这些事件没有办法并发地执行。

  • 异步
    如果有多个任务或者事件发生(主要指 IO 事件),都交给操作系统执行我们就可以去做别的事情并不需要真正的完成 IO 操作,当操作完成之后给我们的应用程序一个通知就可以。

  • 网络种数据传输与内核之间的关系:
    消息由发送方产生,从发送方的用户空间传入内核空间借助网络传输介质完成传输,消息会发送到接收方的内核空间,接收方如果要想读取时需要将消息从内核空间拷贝到用户空间。

在这里插入图片描述
上面的概念如果都清楚了,ok,开始正式内容

一、同步阻塞模型

模型特点:
在Linux中,对于一次读取IO的操作,数据并不会直接拷贝到程序的缓冲区。通常包括两个不同的阶段:

  • 等待数据准备好,到达内核缓冲区
  • 从内核向进程复制数据。对于套接字上的输入操作,第一步通常涉及等待数据从网络中到达。当所有分组到达时,它被复制到内核中的某个缓冲区。第二步就是把数据从内核缓冲区复制到应用程序缓冲区

上面的话太官方了,上栗子:

  • 话说那是夜黑风高的一夜,小明从家去演唱会买票,但是票卖完了,要三天后才有票,小明说:我等,就一直等到有票,然后买票
  • 图示:
    在这里插入图片描述

二、同步非阻塞模型

模型特点:

  • 与阻塞式I/O不同的是,非阻塞的recvfrom系统调用之后,进程并没有被阻塞,内核马上返回给进程,如果数据还没有处理好,此时返回一个error。进程在返回之后,可以处理其它的业务,过会儿再发起recvform系统调用。采用轮询的方式检查内核数据,直到数据准备好。再拷贝数据到进程,进程数据处理。在linux下,可以通过设置socket套接字选项使其变为非阻塞

栗子:

  • 又是一个夜黑风高的夜晚,小明又出来看演唱会了,可惜票卖完了,小明走了,办理别的事情去了,过了两个小时,小明又去卖票厅,如果票还没出来,小明又去办别的事情,重复上面事情,直到买到票
  • 图示:
    在这里插入图片描述

三、I/O复用模型(事件驱动)

模型特点:

  • IO多路复用的好处就在于单个进程可以同时处理多个网络连接的IO。它的基本原理就不再是由用用程序自己监视链接,取而代之由内核代替应用程序监视文件描述符。以:select为例,当用户进程调用了select,那么整个进程就会被阻塞,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这时候用户进程在调用read操作,将数据从内核拷贝到用户进程

栗子:

  • 小明想去演唱会,买票时候直接打电话给黄牛(selector/epoll),说帮我留意买票,有票通知我,我自己去取(当我接收到黄牛的电话,我需要花费整个路程时间去读这个数据,拿这个票),那么票没出来之前,小明完全做自己的事

  • 图示:
    在这里插入图片描述

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

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

四、信号I/O模型

模型特点:

  • 允许Socket进行信号驱动IO,并注册一个信号处理函数,进程继续运行并不阻塞。当数据准备好时,进程会收到一个SIGIO信号,可以在信号处理函数调用I/O操作函数处理数据

栗子:

  • 小明想去看演唱会,给举办商说:给你留个电话,有票给我提前打电话通知(是看人家操作系统提不提供这种功能,linux提供,windows没有这种机制),我自己再来买票(小明完全可以做自己事情,但是票还是需要小明去拿)

  • 图示:
    在这里插入图片描述

  • 信号驱动IO模型,应用进程告诉内核:当数据报准备好的时候,给我发送一个信号,对SIGIO信号进行捕捉,并且调用我的信号处理函数来获取数据报

五、异步非阻塞模型

模型特点:

  • 上述四个模型都是同步的。相对于同步来说,异IO不是顺序执行的。用户进程执行aio_read系统调用之后,就可以处理其他事情了,无论内核数据是否准备好了,都会直接返回给用户进程,不会对进程造成阻塞。等数据准备好了,内核直接复制数据到进程空间,然后从内核向进程发送通知,此时数据已经在用户空间了,可以对数据处理

栗子:

  • 小明想买票去看演唱会,给举办商打电话(异步非阻塞i/o),给你留个地址,有票了请通知快递员给我送到,当小明听到敲门声,看见快递员,就知道票到了,而且直到票到了的时候,票已经到手了,不用自己去取(不用自己去read数据了)

  • 图示:
    在这里插入图片描述

  • 当应用程序调用aio_read时,内核一方面去取数据报内容返回,另一方面将程序控制权还给应用进程,应用进程继续处理其他事情,是一种非阻塞的状态

  • 当内核中有数据报就绪时,由内核将数据报拷贝到应用程序中,返回aio_read中定义好的函数处理程序

总结: 可以看出,阻塞程度:阻塞IO>非阻塞IO>多路转接IO>信号驱动IO>异步IO,效率是由低到高的

想了解更多,请看:大白话五种IO模型

猜你喜欢

转载自blog.csdn.net/qq_44682003/article/details/110558873
今日推荐