I/O模型(同步阻塞I/O,同步非阻塞I/O,I/O多路复用,信号驱动I/O,异步I/O)

1、I/O是什么?

根据冯·诺依曼结构,计算机结构分为5大部分:运算器、控制器、存储器、输入设备、输出设备。
I/O模型(同步阻塞I/O,同步非阻塞I/O,I/O多路复用,信号驱动I/O,异步I/O)_第1张图片
从计算机结构上来说,IO就是计算机系统和外部设备(输入设备、输出设备,硬盘等也属于外部设备)之间的通信的过程。
从应用程序上看,为了保证操作系统的稳定性和安全性,一个进程的地址空间分为用户空间(User space)内核空间(Kernel space)
我们平时运行的应用程序都是运行在用户空间的,只用内核空间才能进行系统态级别的资源操作,如文件管理、内存管理,进程通信等。而用户空间的程序是不能直接访问内核空间的。所以要进行IO操作,必须依赖内核空间的能力。
IO(Input/Output 输入/输出)即数据的读取(接收)和写入(发送)操作,通常用户进程一个完整的IO分为两个阶段:用户空间<——>内核空间,内核空间<——>设备空间(磁盘、网络等)IO有内存IO、磁盘IO、网络IO三种,一般IO说的是指后两种。
I/O模型(同步阻塞I/O,同步非阻塞I/O,I/O多路复用,信号驱动I/O,异步I/O)_第2张图片
从应用程序的角度看,我们应用程序对操作系统的内核发起IO调用(系统调用),内核执行具体的IO操作。
进程IO系统调用后,内核会首先看缓冲区中有没有相应的缓存数据,有数据则直接复制到进程空间(用户空间),没有的话再到设备中取(磁盘),因为磁盘IO一般数据较慢,需要等待。
所以当应用程序发起IO调用后,会经历两个步骤:
(1)内核等待IO设备准备好数据。
(2)内核将数据从内核空间拷贝到用户空间

2、五种I/O模型

UNIX系统下,I/O模型一共分为五种:同步阻塞I/O,同步非阻塞I/O,I/O多路复用,信号驱动I/O,异步I/O
Java中有3中常见的I/O模型:
(1)BIO同步阻塞I/O
(2)NIOI/O多路复用
(3)AIO异步I/O

3、同步阻塞I/O

I/O模型(同步阻塞I/O,同步非阻塞I/O,I/O多路复用,信号驱动I/O,异步I/O)_第3张图片
进程发起I/O调用后,进程被阻塞,转到内核空间处理,整个I/O处理完后返回进程,操作成功则获取到数据。

通俗来说,就是A拿着一根鱼竿钓鱼,在钓鱼的过程中,什么事都不干,一直等待上钩,有上钩,则钓起来,在开始下一次的钓鱼或者做其他事。

应用:阻塞scoketJava BIO
特点:进程阻塞挂起不消耗CPU资源,及时响应每个操作,使用于并发量小的应用开发,不适用于高并发,因为请求I/O会阻塞进程,需要为每一个请求分配一个处理进程,系统开销大。

4、同步非阻塞I/O

I/O模型(同步阻塞I/O,同步非阻塞I/O,I/O多路复用,信号驱动I/O,异步I/O)_第4张图片

进程发起IO系统调用后,内核的缓冲区中如果有相应的数据,则直接返回数据给进程,如果没有,则到IO设备中取数据,进程返回一个错误而不会被阻塞,每隔一定的时间,应用程序会不断进行IO系统调用轮询内核数据是否已经准备好,没有,则返回一个错误,有则返回数据。注意,返回数据时,等待数据从内核空间拷贝到用户空间的这段时间,进程依然是阻塞的,直到拷贝完成。

通俗来说,A拿着一根鱼竿钓鱼,在等待上钩的过程中,A可以去干其他的事,比如玩会手机、看看书、上个厕所等,只不过隔一段时间就看下是否有上钩,一旦有上钩,就停下手中的事,把钓起来。把钓起来的这段过程中,A是干不了其他的事的。

特点:进程轮询(重复)调用,消耗CPU资源。适用于并发量小,不需要即使相应的应用程序。

5、I/O多路复用模型

I/O模型(同步阻塞I/O,同步非阻塞I/O,I/O多路复用,信号驱动I/O,异步I/O)_第5张图片
多个进程的I/O注册到一个复用器(select)上,在用一个进程调用这个复用器,select会监听所有注册的I/O
如果select监听的I/O在内核中都没有可读数据,则这个select调用进程会阻塞,当任一I/O调用在内核缓存区中有可读数据时,select进程就会返回,而后,select调用进程可以自己或通知注册的I/O进程再次发起读取I/O,把内核中的数据读到用户空间中。所有,当多个进程注册I/O后,就只会有一个select调用进程会被阻塞。
当然,某个进程把数据从内核空间读取到用户空间这段时间,对于这个进程而言,是阻塞的。

支持多路复用的系统调用:
(1)select 调用 :内核提供的系统调用,它支持一次查询多个系统调用的可用状态。几乎所有的操作系统都支持。
(2)epoll调用 :linux 2.6 内核,属于select 调用的增强版本,优化了IO 的执行效率。

通俗来说,A比较有钱,一次带十几根鱼竿去钓鱼,一次性有十几根鱼竿在等待上钩,A不停的查看每个鱼竿,那只鱼竿有上钩,就去那个鱼竿那把钓起来。

典型运用:select、poll、epoll三种方法,nginx可选这三种方案;Java NIO
特点:专一进程解决多个进程阻塞问题,效率高。适用于高并发。

6、信号驱动I/O模型

I/O模型(同步阻塞I/O,同步非阻塞I/O,I/O多路复用,信号驱动I/O,异步I/O)_第6张图片
进程发起I/O系统调用时,会在内核中注册一个信号处理函数,然后进程返回不阻塞,当内核中数据已经准备好就会发送一个信号给进程,进程在信号处理函数中调用I/O读取函数。

通俗来说,A拿着一根鱼竿去钓鱼,他比较聪明,在鱼竿上绑了一个铃铛,然后就去干其他的事了不再关注鱼竿这了,铃铛响了,说明有上钩了,就过来把给钓起来。

7、异步I/O模型

I/O模型(同步阻塞I/O,同步非阻塞I/O,I/O多路复用,信号驱动I/O,异步I/O)_第7张图片
进程发起I/O系统调用,进程返回(不阻塞),但是也不会返回结果,当内核把整个I/O处理完后,会通知进程结果,进程直接获取到数据。
当应用程序调用aio_read时,内核一方面去获取数据返回,另一方面把程序的控制权还给应用程序,应用程序可以去干其他的事,所以非阻塞。当内核中数据准备好后,由内核将数据拷贝到应用程序中,返回aio_read中处理好的函数处理程序。即内核将整个I/O过程处理完后(内核把数据拷贝到用户空间),再通知进程。而信号驱动I/O是内核中数据准备好了,通知进程调用I/O,读取数据。

通俗来说,A去钓鱼,但是他有其他的事要忙,就雇佣B帮他钓鱼,当B把钓起来后,就打电话通知A,A过来把拿走。

典型应用:Java7 AIO;
特点:非常适合高性能高并发应用,但是实现、开发难度较大。

综上而言,就阻塞程度:同步阻塞I/O>同步非阻塞I/O>I/O多路复用>信号驱动I/O>异步I/O

你可能感兴趣的:(java基础,多进程,linux,内核,操作系统)