I/O交互流程
一个完整的I/O交互流程分为量阶段:1、首先是经过内核空间也就是系统处理,2、然后就到用户空间,也就是应用程序。 内核空间中存放是内核代码和数据,而进程的用户空间中存放的用户程序的代码和数据,不管是内核孔家还是用户空间,都处于虚拟空间中。Linux使用两级保护机制:0是供内核使用,3级是供用户程序使用。每个进程都有各自的私有空间(0-3G),这个空间未系统中奇特进程是不可见的。最高的1G字节虚拟空间则为所有进程及内核共享。
操作系统运行在内核空间,应用程序运行在用户空间,两者不能简单低使用指针传递数据。因为Linux使用的虚拟内存机制,必须通过系统请求Kernel来协助完成I/O操作,内核会为每个I/O设备维护一个缓冲区,用户空间的数据可能被换出,所以当内核空间使用用户空间的指针,对应的数据可能不在内存中。
对于一个输入操作看来说,进程I/O系统调用后,内核会先看缓冲区内有没有相应的缓存数据,如果没有再到设备中读取,因为设备I/O速度一般较慢,内核缓冲区有数据则直接复制到用户的进程空间,所以一个网络的输入操作通畅包括两个不同的阶段。
- 等待网络数据达到网卡,然后将数据读取到内核缓冲区。
- 从内核缓冲区复制数据,然后拷贝到用户空间。
I/O有内存I/O、网络I/O和磁盘I/O三种,通常我们说的IO指的是后两者。
五种I/O通信模型
在网络环境中,I/O分为:第一步是等待,第二步时数据迁移。
阻塞IO模型
几乎所有的开发者第一次接触网络编程都是从listen()、send()、recv()开始,这些全部都是阻塞的。
特点 | 在I/O执行的两个阶段(等待数据和拷贝数据)都是阻塞 |
---|---|
典型应用 | 阻塞Socket、Java BIO |
优点 | 1. 塞挂起不消耗CPU资源,及时响应每个操作 2.难度底,开发应用较容易3.适合并发量小的网络应用开发 |
缺点 | 1.不适合并发量大的应用,因为每个请求I/O会阻塞进程2.需要为每个请求分配一个处理进程以及是响应,系统开销大 |
非阻塞IO模型
与阻塞比,当用户进程发出read操作适合,如果内核没有数据准备好,他不会阻塞用户进程,而是立刻返回error。从用户进程角度来讲,它发起一起read操作后,不需要等待,而是马上有一个结果
特点 | 用户进程需要不断的主动轮询内核(kernel)数据准备好了么 |
---|---|
典型应用 | Socket设置了NON BLOCK |
优点 | 实现难度低,开发应用想对阻塞I/O模型较难 |
缺点 | 1.进程轮询调用,消耗CPU的资源2.适合并发量小且不需要及时响应的网络应用开发 |
多路复用IO模型
多个进程的I/O可以注册到一个复用器(Selector)上,当用户进程调用该Selector,Selector会监听注册进程的所有I/O,如果Selector监听的所有I/O再内核缓冲区都没有可读数据,select调用的进程会被阻塞,当任一I/O在内核缓冲区中有可读数据时,select调用就会返回,而后select调用进程可以自己或通知另外的进程再次发起读取I/O,读取内核中准备好的数据,多个进程注册I/O后,只有一个select调用进程被阻塞。
特点 | 对于每一个Socket,一般都设置成非阻塞,但是整个用户的进程其实是一直被阻塞的,只不过进程是被select函数阻塞,而不是被Socket I/O阻塞 |
---|---|
典型应用 | Java Nio,nginx(epoll,poll,select) |
优点 | 1. 专一进程解决多个进程I/O的阻塞问题,性能好,Reactor模式 2.适合高并发服务应用开发,一个进程/线程响应多个请求 |
缺点 | 实现和开发难度较大 |
信号驱动IO模型
信号驱动I/O是指进程会预先告知内核,向内核注册一个信号处理函数,然后用户进程返回不阻塞,当内核数据就绪会发送一个信号给进程,用户进程便在信号处理函数中调用I/O读取数据,实际上I/O内核拷贝到用户进程的过程还是阻塞的,信号驱动I/O并没有实现真正的异步,因为通知到进程之后,依然由进程来完成I/O操作。这和后面的异步I/O模型很容易混淆
特点 | 并不符合异常I/O要求,只能算是伪异步,并求实际中并不常用 |
---|---|
典型应用 | 应用场景少 |
优点 | 应用少,不总结 |
缺点 | 实现和开发难度较大 |
异步IO模型
用户进程发起aio_read操作后,给内核传递与read相同的描述符、缓冲区指针、缓冲区大小三个参数及文件偏移,告诉内核当整个操作完成时,如何通知我们立刻可以开始去做其他事。而另一方面,从内核的角度,当它收到一个aio_read之后,首先他会立刻返回,所有不会对用户进程产生阻塞,内核会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,内核会给用户进程发送一个信号,告诉他aio_read操作完成。
特点 | 正在实现了异步I/O,是五种I/O模型中唯一的异步模型 |
---|---|
典型应用 | Java7AIO,高性能服务器采用 |
优点 | 1. 不阻塞,数据一步到位,采用Proactor模式 2.非常适合高性能、高并发应用 |
缺点 | 1. 需要操作系统的底层支持,Linux2.5内核首现,Linux2.6产品内核核心特征 2.实现和开发应用难度大 |
注意:本文归作者所有,未经作者允许,不得转载