内核的IO模型详解
Posted 正在起飞的蜗牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内核的IO模型详解相关的知识,希望对你有一定的参考价值。
1、什么是I/O?
(1)I/O系统就是操作系统负责输入、输出信息的系统,也可以说是整个操作系统数据交换与人机交互的通道。比如常见的键盘、鼠标、显示屏就是I/O设备;
(2)数据输入:外部IO设备把数据输入到内存;数据输出:内存中的数据输出到I/O设备;
2、提高I/O性能的方法
(1)从硬件上着手,提高I/O设备本身的读写速度。比如将机械硬盘换成固态硬盘,就可以明显提高读写速度;但是硬件有自己的物理特性,不是想提高就能提高的;
(2)从软件上着手,给I/O设备添加缓冲区,减少CPU操作I/O设备的次数,用空间换取时间。比如用串口传数据,如果没有缓冲区,则每发一个字节数据,CPU都要去处理一次,有了缓冲区,CPU可以一次处理缓冲区大小的数据;
3、I/O模型类型划分
3.1、阻塞IO
3.1.1、处理流程
(1)应用进程发起IO调用,内核数据没有准备好,则进程阻塞被挂起,在被阻塞期间不能做其他的操作;
(2)内核准备好数据,并且把数据从内核区拷贝到用户空间;
(3)当内核把数据拷贝完成,应用调用的IO函数才返回;
3.1.2、优缺点:
(1)优点:能够及时返回数据,无延迟,因为一直在监视内核是否准备好数据;
(2)优点:对内核开发者来说这是省事了,实现逻辑简单;
(3)优点:阻塞期间不占用系统资源,因为进程被挂起;
(4)缺点:对用户来说处于等待就要付出性能的代价了,在等待期间进程不能做其他的操作;
3.2、非阻塞IO
3.2.1、处理流程
(1)应用进程发起IO调用,无论内核准备好数据都立马返回
(2)检测IO调用是否获取到数据,如果没有获取到就等待一段时间再次发起IO调用尝试获取数据;
(3)在两个IO操作的等待期间,进程可以进行其他的操作;
(4)直到操作系统内核数据准备好了,从内核缓冲区拷贝到用户空间,完成调用;
3.2.2、优缺点:
(1)优点:能够在等待任务完成的时间里干其他活了;
(2)缺点:任务完成的响应延迟增大了,因为每过一段时间才去轮询一次read操作,而任务可能在两次轮询之间的任意时间完成,这会导致整体数据吞吐量的降低;
3.3、异步IO
3.3.1、处理流程
(1)异步IO通过aio_read函数实现, aio_read提交请求, 并递交一个用户态空间下的缓冲区。 即使内核中没有数据到来,aio_read函数也立刻返回, 应用程序就可以处理其他的事情;
(2)当数据到来后, 操作系统自动把数据从内核空间拷贝到aio_read函数递交的用户态缓冲区。 拷贝完成以信号的方式通知用户态程序, 用户态程序拿到数据后就可以执行后续操作
3.3.2、优缺点:
(1)优点:异步IO是一种推数据的机制,相比于信号处理IO拉数据的机制效率更高;
(2)优点:异步IO主动把数据拷贝到用户态空间,不需要调用recv方法把数据从内核空间拉取到用户态空间;
3.3.3、异步IO和信号驱动IO的不同:
在于内核向应用进程发信号通知时,数据所在的位置。
(1)信号驱动IO:应用进程收到信号后,数据还在内核空间,应用进程需要调read函数将数据从内核空间拷贝到用户空间;
(2)异步IO:应用进程收到信号后,数据已经拷贝到用户进程调用aio_read()函数时提交的用户空间缓冲区;
3.4、信号驱动IO
3.4.1、处理流程
(1)应用进程首先绑定SIGIO信号处理函数,也就是数据的读取/写入函数,当进程收到SIGIO信号就去处理设备;
(2)打开文件,设置文件的FASYNC标志,这样文件有数据后内核才会发SIGIO信号给进程;
(3)进程收到SIGIO信号,自动调用绑定的数据处理函数去接收数据;
3.4.2、优缺点:
(1)优点:进程不必阻塞,而且给SIGIO信号绑定了数据处理函数,所以进程的主任务不必关系数据的处理;
3.4.3、驱动中支持信号驱动I/O
驱动代码支持信号驱动I/O,参见博客:《信号驱动I/O详解》;
3.5、IO多路复用
3.5.1、IO多路复用原理
I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。slect()、poll()、epoll()是Linux API提供的I/O复用方式。
3.5.2、slect()、poll()、epoll()函数详解
3.5.3、三种方式性能对比
3.5.3.1、slect优缺点
(1)单个进程可监视的fd数量被限制,即能监听端口的大小有限,一般是1024;
(2)对socket进行扫描时是线性扫描,即采用轮询的方法,效率较低;
(3)需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大;
3.5.3.2、poll优缺点
(1)和select函数一样,监听多个文件描述符,直到条件满足或超时的时候poll返回,通过遍历文件描述符来获取已经就绪的描述符;
(2)不同于select使用三个位图来表示三个fdset的方式,poll使用一个pollfd的指针实现;
(3)pollfd并没有最大数量限制,同时连接的大量客户端在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长,
其效率也会线性下降;
3.5.3.3、epoll优缺点
(1)epoll是在2.6内核中提出的,是select和poll的增强版本;
(2)监视的描述符数量不受限制。所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大;
(3)IO的效率不会随着监视fd的数量的增长而下降。epoll不同于select和poll轮询的方式,而是通过每个fd定义的回调函数来实现的,只有就绪的fd才会执行回调函数;
(4)epoll使用一个文件描述符管理多个描述符。将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次;
4、参考的资源:
(1)https://baijiahao.baidu.com/s?id=1718409483059542510&wfr=spider&for=pc;
(2)《一口linux》
以上是关于内核的IO模型详解的主要内容,如果未能解决你的问题,请参考以下文章