详解磁盘IO、网络IO、零拷贝IO、BIO、NIO、AIO、IO多路复用(select、poll、epoll)

您所在的位置:网站首页 linux直接io如何申请bio 详解磁盘IO、网络IO、零拷贝IO、BIO、NIO、AIO、IO多路复用(select、poll、epoll)

详解磁盘IO、网络IO、零拷贝IO、BIO、NIO、AIO、IO多路复用(select、poll、epoll)

2024-07-09 08:47| 来源: 网络整理| 查看: 265

文章很长,但是很用心!

文章目录 1. 什么是I/O 2. 磁盘IO 3. 网络IO 4. IO中断与DMA 5. 零拷贝IO 6. BIO 7. NIO 8. IO多路复用 8.1 select 8.2 poll 8.3 epoll 9. AIO 10. 总结

1. 什么是I/O

在计算机操作系统中,所谓的I/O就是输入(Input)和输出(Output),也可以理解为读(Read)和写(Write),针对不同的对象,I/O模式可以划分为磁盘IO模型和网络IO模型。

IO操作会涉及到用户空间和内核空间的转换,先来理解以下规则:

内存空间分为用户空间和内核空间,也称为用户缓冲区和用户缓冲区 用户的应用程序不能直接操作内核空间,需要将数据从内核空间拷贝到用户空间才能使用 无论是read操作,还是write操作,都只能在内核空间里执行 磁盘IO和网络IO请求加载到内存的数据都是先放在内核空间的

再来看看所谓的读(Read)和写(Write)操作:

读操作:操作系统检查内核缓冲区有没有需要的数据,如果内核缓冲区已经有需要的数据了,那么就直接把内核空间的数据copy到用户空间,供用户的应用程序使用。如果内核缓冲区没有需要的数据,对于磁盘IO,直接从磁盘中读取到内核缓冲区(这个过程可以不需要cpu参与)。而对于网络IO,应用程序需要等待客户端发送数据,如果客户端还没有发送数据,对应的应用程序将会被阻塞,直到客户端发送了数据,该应用程序才会被唤醒,从Socket协议找中读取客户端发送的数据到内核空间,然后把内核空间的数据copy到用户空间,供应用程序使用。 写操作:用户的应用程序将数据从用户空间copy到内核空间的缓冲区中(如果用户空间没有相应的数据,则需要从磁盘—>内核缓冲区—>用户缓冲区依次读取),这时对用户程序来说写操作就已经完成,至于什么时候再写到磁盘或通过网络发送出去,由操作系统决定。除非应用程序显示地调用了sync命令,立即把数据写入磁盘,或执行flush()方法,通过网络把数据发送出去。 绝大多数磁盘IO和网络IO的读写操作都是上述过程,除了后面要讲到的零拷贝IO。 2. 磁盘IO

磁盘IO的流程如下图所示:

(1)读操作

当应用程序调用read()方法时,操作系统检查内核缓冲区中是否存在需要的数据,如果存在,那么就直接把内核空间的数据copy到用户空间,供用户的应用程序使用。如果内核缓冲区没有需要的数据,通过通过DMA方式(一种IO设备控制方式,下面会讲解)从磁盘中读取数据到内核缓冲区,然后由CPU控制,把内核空间的数据copy到用户空间。

这个过程会涉及到两次缓冲区copy,第一次是从磁盘的缓冲区到内核缓冲区,第二次是从内核缓冲区到用户缓冲区(或应用缓冲区),第一次是cpu的copy,第二次是DMA的copy。

(2)写操作

当应用程序调用write()方法时,应用程序将数据从用户空间copy到内核空间的缓冲区中(如果用户空间没有相应的数据,则需要从磁盘—>内核缓冲区—>用户缓冲区依次读取),这时对用户程序来说写操作就已经完成,至于什么时候把数据再写到磁盘(从内核缓冲区到磁盘的写操作也由DMA控制,不需要cpu参与),由操作系统决定。除非应用程序显示地调用了sync命令,立即把数据写入磁盘。

如果应用程序没准备好写的数据,则必须先从磁盘读取数据才能执行写操作,这时会涉及到四次缓冲区的copy,第一次是从磁盘的缓冲区到内核缓冲区,第二次是从内核缓冲区到用户缓冲区,第三次是从用户缓冲区到内核缓冲区,第四次是从内核缓冲区写回到磁盘。前两次是为了读,后两次是为了写。这其中有两次cpu拷贝,两次DMA copy。

(3)磁盘IO的延时

为了读或写,磁头必须能移动到所指定的磁道上,并等待所指定的扇区的开始位置旋转到磁头下,然后再开始读或写数据。磁盘IO的延时分成以下三部分:

寻道时间:把磁头移动到指定磁道上所经历的时间 旋转延迟时间 :指定扇区移动到磁头下面所经历的时间 传输时间 :数据的传输时间(数据读出或写入的时间)

img

3. 网络IO

网络IO的流程如下:

(1)读操作

网络IO的既可以从物理磁盘中读数据,也可以从socket中读数据(从网卡中获取)。当从物理磁盘中读数据的时候,其流程和磁盘IO的读操作一样。当从socket中读数据,应用程序需要等待客户端发送数据,如果客户端还没有发送数据,对应的应用程序将会被阻塞,直到客户端发送了数据,该应用程序才会被唤醒,从Socket协议找中读取客户端发送的数据到内核空间(这个过程也由DMA控制),然后把内核空间的数据copy到用户空间,供应用程序使用。

(2)写操作

为了简化描述,我们假设网络IO的数据从磁盘中获取,读写操作的流程如下:

当应用程序调用read()方法时,通过DMA方式将数据从磁盘拷贝到内核缓冲区 由cpu控制,将内核缓冲区的数据拷贝到用户空间的缓冲区中,供应用程序使用 当应用程序调用write()方法时,cpu会把用户缓冲区中的数据copy到内核缓冲区的Socket Buffer中 最后通过DMA方式将内核空间中的Socket Buffer拷贝到Socket协议栈(即网卡设备)中传输。

网络IO的写操作也有四次缓冲区的copy,第一次是从磁盘缓冲区到内核缓冲区(由cpu控制),第二次是内核缓冲区到用户缓冲区(DMA控制),第三次是用户缓冲区到内核缓冲区的Socket Buffer(由cpu控制),第四次是从内核缓冲区的Socket Buffer到网卡设备(由DMA控制)。四次缓冲区的copy工作两次由cpu控制,两次由DMA控制。

(3)网络IO的延时

网络IO主要延时是由:服务器响应延时+带宽限制+网络延时+跳转路由延时+本地接收延时 决定。一般为几十到几千毫秒,受环境影响较大。所以,一般来说,网络IO延时要大于磁盘IO延时。

4. IO中断与DMA

以前传统的IO读写是通过中断由cpu控制的,为了减少CPU对I/O的干预,引入了直接存储器访问方式(DMA)方式。在DMA方式下,数据的传送是在DMA的控制下完成的,不需要cpu干预,所以CPU和I/O设备可以并行工作,提高了效率。现在来看看它们各自的原理:

(1)IO中断原理

用户进程通过read等系统调用接口向操作系统(即CPU)发出IO请求,请求读取数据到自己的用户内存缓冲区中,然后该进程进入阻塞状态。 操作系统收到用户进程的请求后,进一步将IO请求发送给磁盘。 磁盘驱动器收到内核的IO请求后,把数据读取到自己的缓冲区中,此时不占用CPU。当磁盘的缓冲区被读满之后,向内核发起中断信号告知自己缓冲区已满。 内核收到磁盘发来的中断信号,使用CPU将磁盘缓冲区中的数据copy到内核缓冲区中。 如果内核缓冲区的数据少于用户申请读的数据,则重复步骤2、3、4,直到内核缓冲区的数据符合用户的要求为止。 内核缓冲区的数据已经符合用户的要求,CPU停止向磁盘IO请求。 CPU将数据从内核缓冲区拷贝到用户缓冲区,同时从系统调用中返回。 用户进程读取到数据后继续执行原来的任务。

中断IO缺点:每次IO请求都需要CPU多次参与。

(2)DMA原理

用户进程通过read等系统调用接口向操作系统(即CPU)发出IO请求,请求读取数据到自己的用户内存缓冲区中,然后该进程进入阻塞状态。 操作系统收到用户进程的请求后,进一步将IO请求发送给DMA,然后CPU就可以去干别的事了。 DMA将IO请求转发给磁盘。 磁盘驱动器收到内核的IO请求后,把数据读取到自己的缓冲区中,当磁盘的缓冲区被读满后,向DMA发起中断信号告知自己缓冲区已满。 DMA收到磁盘驱动器的信号,将磁盘缓存中的数据copy到内核缓冲区中,此时不占用CPU(IO中断这里是占用CPU的)。 如果内核缓冲区的数据少于用户申请读的数据,则重复步骤3、4、5,直到内核缓冲区的数据符合用户的要求为止。 内核缓冲区的数据已经符合用户的要求,DMA停止向磁盘IO请求。 DMA发送中断信号给CPU。 CPU收到DMA的信号,知道数据已经准备好,于是将数据从内核空间copy到用户空间,系统调用返回。 用户进程读取到数据后继续执行原来的任务。

跟IO中断模式相比,DMA模式下,DMA就是CPU的一个代理,它负责了一部分的拷贝工作,从而减轻了CPU的负担。

需要注意的是,DMA承担的工作是从磁盘的缓冲区到内核缓冲区或网卡设备到内核的soket buffer的拷贝工作,



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3