理解五种网络模型和零拷贝的原理

2023年 7月 12日 76.7k 0

前置知识:

计算机系统中,应用是没办法直接操纵内存的,应用属于用户态,操纵内存(硬件)需要内核态,也是防止用户态权限过大

image.png
所有IO

  • 阻塞IO(Blocking IO)
  • 非阻塞IO(Nonblocking IO)
  • IO多路复用(IO Multiplexing)
  • 信号驱动IO(Signal Driven IO)
  • 异步IO(Asynchronous IO)

阻塞IO(Blocking IO)

image.png

应用是无法直接从磁盘上读取数据的,分为两步:

  • 用户空间等待内核空间从硬件中拿到数据
  • 再把这个数据写给用户缓存去
  • 这是一个阻塞的过程,两个阶段都要等待

    image.png

    非阻塞IO(Nonblocking IO)

    image.png

  • 用户会一直尝试获取数据,因为内核里没有数据
  • 直到内核台有数据了,再阻塞用户进程,拷贝数据
  • IO多路复用(IO Multiplexing)

    文件描述符(File Descriptor):简称FD,是一个从0 开始的无符号整数,用来关联Linux中的一个文件。在Linux中,一切皆文件,例如常规文件、视频、硬件设备等,当然也包括网络套接字(Socket)。

    通过FD,我们的网络模型可以利用一个线程监听多个FD,并在某个FD可读、可写时得到通知,从而避免无效的等待,充分利用CPU资源。

    image.png

  • 调用select,指定要监听的FD集合(用户态告诉内核态,这些FD有一个好了就和我说)
  • 内核态通知,用户态recvfrom读取数据,此时肯定是有数据的
  • 监听的多种方式: select、poll、 epoll

    其中select和pool相当于是当被监听的数据准备好之后,他会把你监听的FD整个数据都发给你,你需要到整个FD中去找,哪些是处理好了的,需要通过遍历的方式,所以性能也并不是那么好

    而epoll,则相当于内核准备好了之后,他会把准备好的数据,直接发给你,咱们就省去了遍历的动作。

    epoll模式中如何解决这些问题的?

    • 基于epoll实例中的红黑树保存要监听的FD,理论上无上限,而且增删改查效率都非常高
    • 每个FD只需要执行一次epoll_ctl添加到红黑树,以后每次epol_wait无需传递任何参数,无需重复拷贝FD到内核空间
    • 利用ep_poll_callback机制来监听FD状态,无需遍历所有FD,因此性能不会随监听的FD数量增多而下降

    信号驱动IO

    image.png

    这种相当于 用户态告诉内核态:我要这个的数据,我看你这里没有,搞好了告诉我,我先去搞别的东西。等东西搞好了,内核态通知用户态可以来拿数据了,用户态调用recvfrom(阻塞)并返回数据

    异步IO

    image.png

    这一步就是最后数据是由内核态直接传给用户态的

    零拷贝

    比如我现在要做一个文件传输系统,系统的文件流程大概是这样的:

    image.png

    (DMA是Direct Memory Access 直接访问内存的一个技术)

    可以看到文件反复复制,拷贝了4次

    进程状态切换了四次

    零拷贝:

    image.png

    优化的几个点:

  • 用户缓冲区和内核态缓冲区共享一个
  • 内核态直接CPU拷贝到socket缓冲区
  • mmap() 系统调用函数会直接把内核缓冲区里的数据映射到用户空间,这样,操作系统内核与用户空间就不需要再进行任何的数据拷贝操作。
  • linux内核提供了一个sendfile函数,又可以优化一些:

    image.png

    所谓零拷贝,我认为就是这一层“用户态和内核态之间”零拷贝吧

    详细请看:www.xiaolincoding.com/os/8_networ…

    图源:黑马Redis & 小林coding

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论