Skip to main content

网络系统

什么是零拷贝

  • DMA(Direct Memory Access):直接内存访问机制。可以用于将磁盘缓冲区数据拷贝至内核缓冲区,此过程不占用CPU资源。

以一个网络文件系统为例,当用户请求文件数据时,我们最常用的就是read+write模式。

在这种模式下,我们需要先将文件数据从磁盘读取到用户空间,再将数据写到网络文件句柄中,也就是我们常说的socket。

这个过程需要的CPU提供计算支撑。并且涉及到多次用户态与内核态的切换。

零拷贝的原理,则是linux提供sendfile接口,支持一次调用,就可以将具体的文件数据写入到对应的网络文件句柄中。

内核将磁盘数据读取到内核缓存中,并直接将缓存数据写出,从而实现了零拷贝技术。

什么是IO多路复用

再传统的后端服务模型中,一般是分配一个线程或者进程来处理一个socket句柄。

而线程和进程是系统级资源,对于有限的系统资源来说,端口有限的,文件描述符是有限的,内存空间是有限的。 再这种场景下,相对来讲,线程和进程是重载的,因为我可以轻松占用几千个端口、几千个文件描述符,但我很难启动几千个线程或者进程。 它首先与内存资源,也受限于系统调度。

在这种场景下,IO多路复用诞生,它允许在一个线程同时管理多个socket事件。

select

维护一个文件描述符集合,通过遍历的方式检测网络事件。当检测到由网络事件时,会将集合拷贝到用户态, 由应用层去遍历处理事件。

由于select是数组的实现方式,因此存在最大长度,默认是1024

poll

poll在select的基础上,改用链表的方式维护文件描述符集合,因此不在有长度限制。

epoll

epoll则采用了全新的红黑树存在文件描述符集合。并通过事件驱动机制,在内核维护了链表来记录就绪事件。 当某个网络事件触发后,通过事件回调函数,将文件描述符加入到就绪事件链表中,

epoll 中水平触发以及边缘触发有什么不同

epoll中,水平触发(Level-Triggered,简称LT)和边缘触发(Edge-Triggered,简称ET)是两种不同的事件触发机制,用于通知应用程序关注的文件描述符上是否有事件发生。

  1. 水平触发(LT):
    • 当文件描述符上的事件发生时,epoll会不断通知应用程序,直到应用程序处理完所有待处理的事件,即使事件没有被处理完成。
    • 如果应用程序没有将文件描述符置于非阻塞模式,水平触发可能导致阻塞,因为epoll_wait会等待文件描述符上的事件。
    • LT适用于任何时刻都希望关注文件描述符状态的情况,不仅在事件发生时关注,而且在事件处理中仍然关注。
  2. 边缘触发(ET):
    • 当文件描述符上的事件发生时,epoll只通知应用程序一次,直到下一次该文件描述符上有新事件发生。
    • 边缘触发需要确保文件描述符是非阻塞的,以避免在处理事件时阻塞。
    • ET适用于那些只关心事件发生瞬间的情况,即在事件发生瞬间迅速做出相应的处理,而不需要一直关注文件描述符状态。

总结比较:

  • 水平触发(LT):
    • 不断通知应用程序直到事件处理完成。
    • 适用于随时关注文件描述符状态的情况。
    • 可能导致阻塞,需要考虑非阻塞模式。
  • 边缘触发(ET):
    • 只通知应用程序一次,直到下一次有新事件发生。
    • 适用于只关心事件瞬间发生的情况,提高效率。
    • 要求文件描述符必须是非阻塞的。