各种IO模型,一篇打尽

Posted 支付技术那些事

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了各种IO模型,一篇打尽相关的知识,希望对你有一定的参考价值。



一、阻塞/非阻塞-同步非同步


同步/异步

同步请求:A调用B,B的处理是同步的,在处理完之前他不会通知A,只有处理完之后才会明确的通知A;

异步请求:A调用B,B的处理是异步的,B在接到请求后先告诉A我已经接到请求了,然后异步去处理,处理完之后通过回调等方式再通知A。


同步/异步区别

同步和异步最大的区别就是被调用方的执行方式和返回时机;

同步指的是被调用方做完事情之后再返回;

异步指的是被调用方先返回,然后再做事情,做完之后再想办法通知调用方。


阻塞/非阻塞

阻塞请求:A调用B,A一直等着B的返回,别的事情什么也不干;

非阻塞请求:A调用B,A不用一直等着B的返回,先去忙别的事情了。


阻塞/非阻塞区别

阻塞和非阻最大的区别就是在被调用方返回结果之前的这段时间内,调用方是否一直等待。

阻塞指的是调用方一直等待,别的事情什么都不做;

非阻塞指的是调用方先去忙别的事情。


阻塞/非阻塞和同步/异步的区别

阻塞、非阻塞和同步、异步其实针对的对象是不一样的

阻塞、非阻塞说的是调用者

同步、异步说的是被调用者


二、Linux(UNIX)操作系统五种IO模型


什么是IO

拿一次磁盘文件读取为例,我们要读取的文件是存储在磁盘上的,我们的目的是把它读取到内存中。可以把这个步骤简化成把数据从硬件(硬盘)中读取到用户空间中。


一次完整的钓鱼(IO)操作,是鱼(文件)从鱼塘(硬盘)中转移(拷贝)到鱼篓(用户空间)的过程。


阻塞IO模型

各种IO模型,一篇打尽

阻塞 I/O 是最简单的 I/O 模型,一般表现为进程或线程等待某个条件,如果条件不满足,则一直等下去。条件满足,则进行下一步操作。


应用程序进行 recvfrom 系统调用时将阻塞在此调用,直到该套接字上有数据并且复制到用户空间缓冲区。该模式一般配合多线程使用,应用进程每接收一个连接,为此连接创建一个线程来处理该连接上的读写以及业务处理。


非阻塞IO模型


各种IO模型,一篇打尽


应用进程与内核交互,目的未达到之前,不再一味的等着,而是直接返回。然后通过轮询的方式,不停的去问内核数据准备有没有准备好。如果某一次轮询发现数据已经准备好了,那就把数据拷贝到用户空间中。


应用进程通过 recvfrom 调用不停的去和内核交互,直到内核准备好数据。如果没有准备好,内核会返回error,应用进程在得到error后,过一段时间再发送recvfrom请求。在两次发送请求的时间段,进程可以先做别的事情。


IO复用模型


各种IO模型,一篇打尽

多个进程的IO可以注册到同一个管道上,这个管道会统一和内核进行交互。当管道中的某一个请求需要的数据准备好之后,进程再把对应的数据拷贝到用户空间中。


IO多路转接是多了一个select函数,多个进程的IO可以注册到同一个select上,当用户进程调用该select,select会监听所有注册好的IO,如果所有被监听的IO需要的数据都没有准备好时,select调用进程会阻塞。


信号驱动IO模型


各种IO模型,一篇打尽应用进程在读取文件时通知内核,如果某个 socket 的某个事件发生时,请向我发一个信号。在收到信号后,信号对应的处理函数会进行后续处理。


异步IO模型


各种IO模型,一篇打尽

应用进程把IO请求传给内核后,完全由内核去操作文件拷贝。内核完成相关操作后,会发信号告诉应用进程本次IO已经完成。


5种IO模型对比

各种IO模型,一篇打尽


三、Java中的三种IO模型


各种IO模型,一篇打尽


java IO模型和操作系统IO模型关系

Java中的IO还是借助操作系统的IO模型的,只不过是对操作系统IO模型的封装而已啦。

可以把Java中的BIO、NIO和AIO理解为是Java语言对操作系统的各种IO模型的封装。

java中提供的IO有关的API,在文件处理的时候,其实依赖操作系统层面的IO操作实现的。

比如在Linux 2.6以后,Java中NIO和AIO都是通过epoll来实现的,而在Windows上,AIO是通过IOCP来实现的。


阻塞IO(BIO)

同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。

BIO (Blocking I/O):有一排水壶在烧开水,BIO的工作模式就是,叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。但是实际上线程在等待水壶烧开的时间段什么都没有做。

BIO和NIO都是同步的IO模型,即同步阻塞IO和同步非阻塞IO


非阻塞IO(NIO)

同时支持阻塞与非阻塞模式,但主要是使用同步非阻塞IO。

NIO (New I/O):NIO的做法是叫一个线程不断的轮询每个水壶的状态,看看是否有水壶的状态发生了改变,从而进行下一步的操作。


异步IO(AIO)

异步非阻塞I/O模型。

异步IO指的是异步非阻塞IO。

AIO ( Asynchronous I/O):为每个水壶上面装了一个开关,水烧开之后,水壶会自动通知我水烧开了。


四、Reactor 模式


Reactor 模式跟 IO 模型关系

Reactor 模式跟 IO 模型中的 IO 多路复用模型非常相似

IO 多路复用模型可以看成是 Reactor 模式在 IO 模型上的应用

Reactor 模式在进程-线程模型上的应用。


1. 单进程单线程

各种IO模型,一篇打尽


只有一个进程,监听套接字和连接套接字上的事件都由 Select 来处理。

过程

(1) 如果有建立连接的请求过来,Acceptor 负责接受并与之建立连接,同时将连接套接字加入 Select 进行监听。

(2) 如果某个连接上有读事件则进行 Read->业务处理->Write 等操作。

(3) 如此循环反复。

缺点:会有阻塞,在进行业务处理的时候不能进行其他操作:如建立连接,读取其他套接字上的数据等。


2. 单进程多线程

各种IO模型,一篇打尽


与单进程单线程类似,不同的是该模型将业务处理放在线程中,进程就不会阻塞在业务处理上。

优点:比较完美的进程-线程模型,在 Java 实现中复杂度也不高,很多网络库都是基于此,比如 Netty 。


3. 多进程单线程

各种IO模型,一篇打尽


与非 Reactor 模式中的多进程单线程相似,只是本模式在子进程中使用了 IO 多路复用,实用性一下就上来了。大名鼎鼎的 nginx 就采用这种进程-线程模型。

缺点:子进程还是会阻塞在业务处理上。


4. 多进程多线程


5. 主从进程多线程

各种IO模型,一篇打尽


前面几种 Reactor 模式的进程-线程模型中,连接的建立和连接的读写都是在同一进程中。本模型中将连接的建立和连接读写放在不同的进程中。

过程

(1) 主进程在监听套接字上 Select 阻塞,一旦有请求过来则与之建立连接,并将连接套接字传递给从进程。

(2) 从进程在连接套接字上 Select 阻塞,一旦连接上有数据过来则进行 Read,并将业务通过线程来处理。如果有必要还会向连接 Write 数据。


五、常见组件使用的模型


各种IO模型,一篇打尽

netty-主从-多线程

各种IO模型,一篇打尽


tomcat-单进程多线程

各种IO模型,一篇打尽

各种IO模型,一篇打尽


redis-单进程单线程

各种IO模型,一篇打尽


ngnix-多进程单线程


以上是关于各种IO模型,一篇打尽的主要内容,如果未能解决你的问题,请参考以下文章

IO 模型知多少 | 代码篇

IO 模型知多少 | 代码篇

IO 模型知多少 | 代码篇

网络 一篇博文搞懂五种常见的IO模型

IO模型解惑

网络IO模型Linux IO 模型