[!NOTE] 解决问题:

  1. 内核缓冲区的数据拷贝到用户缓冲区时,需要CPU参与吗?答:需要。

大家都知道一般我们的数据是存储在磁盘上的,应用程序想要读写这些数据肯定就需要加载到内存中。接下来给大家介绍下 PIO 和 DMA 这两种 IO 设备和内存之间的数据传输方式。

PIO 工作原理

img

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

PIO缺点:每次IO请求都需要CPU多次参与,效率很低。

DMA 工作原理

DMA(直接内存访问,Direct Memory Access)。

img

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

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

需要注意的是,DMA承担的工作是从磁盘的缓冲区到内核缓冲区或网卡设备到内核的 soket buffer的拷贝工作,以及内核缓冲区到磁盘缓冲区或内核的 soket buffer 到网卡设备的拷贝工作,而内核缓冲区到用户缓冲区之间的拷贝工作仍然由CPU负责。

可以肯定的是,PIO模式的计算机我们现在已经很少见到了。