美文网首页
深入理解NIO零拷贝

深入理解NIO零拷贝

作者: jhon_11 | 来源:发表于2021-12-12 17:04 被阅读0次

    NIO零拷贝

    普通IO操作流程

    image.png
    1. 用户程序向内核程序发起读请求
    2. cpu从用户模式切换到内核模式,内核模式向磁盘发出读取数据的请求
    3. 磁盘将数据读取到内核空间的缓冲区
    4. 内核将数据从缓冲区拷贝到用户空间的缓冲区
    5. 执行逻辑代码
    6. 执行write方法,将数据写到网络的另一端。
    7. 将数据从用户空间拷贝回内核空间
    8. 将数据真正的写到磁盘或者socket中
      这种方式会导致系统遇到瓶颈,为传统IO操作

    零拷贝

    零拷贝依赖于操作系统,操作系统实现了,则实现,没有实现则没有实现,跟java程序无关。


    image.png
    1. 从图中可以看出对用户空间的数据拷贝已经没了。
    2. 内核空间收到sendfile()申请
    3. 内核空间向磁盘发送数据读取请求
    4. 磁盘将数据读取到内核空间缓冲区
    5. 将数据写入到socket缓冲区中
    6. 通过socket缓冲区向网络客户端发送数据
    7. 结果返回
    8. sendfile()调用返回
      这种操作我们称为零拷贝,相对与上一种情况有了极大的提升。
    思考:

    我们能不能减少磁盘拷贝到内核的情况,而是将磁盘数据直接拷贝到socket缓冲区中??

    第二版零拷贝

    image.png

    这种方式实现了从磁盘空间直接读入Socket缓冲区

    最终版零拷贝

    image.png
    1. 用户程序发送sendfile()指令给内核空间并返回到用户空间
    2. 内核空间从磁盘采用DMA copy将数据从磁盘拷贝到了内核空间
    3. 将内核缓冲区的数据的文件描述符的信息拷贝到socketbuffer,而不是数据。文件描述中含有数据的内存地址等信息。
    4. protocol协议直接通过socketbuffer中读取到文件描述符信息从而找到kernel buffer存储数据的内存地址以及所需读取字符的长度。并将kernel buffer中的数据发送服务端

    内存映射:

    问题:上面的情况用户无法参与到数据的读取与写入的过程,如果用户需要参与呢??
    内存映射文件:
    通过代码的方式将文件映射到系统内核空间,这样修改文件只需要访问内核空间就可以。

    参考

    零拷贝学习
    浅谈Linux下的零拷贝机制
    mmap原理

    相关文章

      网友评论

          本文标题:深入理解NIO零拷贝

          本文链接:https://www.haomeiwen.com/subject/yttsfrtx.html