Skip to main content

11.内核的一些知识

select, poll, 和 epoll

select, poll, 和 epoll 是在 UNIX 和类 UNIX 操作系统上用于多路复用 I/O 的系统调用。它们允许一个进程监视多个文件描述符以确定哪些文件描述符上有可以进行 I/O 操作的数据,从而使程序能够同时处理多个连接或套接字而不必阻塞在每个连接上等待数据。

原理简介

  • select : select 的原理是通过一个被称为文件描述符集合的数据结构来追踪一组文件描述符,然后通过 select() 系统调用来阻塞进程,直到集合中的某个文件描述符准备好进行 I/O 操作。当某个文件描述符准备好时,select 返回,并且进程可以使用额外的系统调用(如 read()write())来进行实际的 I/O 操作。
  • poll : poll 的原理与 select 类似,但它使用了一个 pollfd 结构体数组来追踪文件描述符的状态。进程调用 poll() 系统调用后,内核会检查每个 pollfd 结构体中指定的文件描述符,并返回已准备好进行 I/O 操作的文件描述符的列表。
  • epoll : epoll 的原理是基于事件通知机制,它使用了一个称为 epoll 实例的内核数据结构。进程首先使用 epoll_create() 创建一个 epoll 实例,然后使用 epoll_ctl() 来向内核注册需要监听的文件描述符。当某个文件描述符准备好进行 I/O 操作时,内核会立即将事件通知给进程。进程使用 epoll_wait() 系统调用来等待事件发生,并获取就绪的文件描述符列表。

区别

  • select : select 是最古老的多路复用函数之一,最早出现在 BSD 系统上。它使用了一个 fd_set 数据结构来追踪一组文件描述符,并提供了一个 select() 系统调用,该调用会阻塞进程,直到集合中的某个文件描述符准备好进行 I/O 操作。 select 的缺点之一是,它的性能在文件描述符数量增加时会线性下降,因为它要遍历所有文件描述符来检查状态。此外,select 有一个限制,即最大监视的文件描述符数量,通常是 1024 或更少。
  • poll : poll 是对 select 的改进,它也是在 UNIX 系统上用于多路复用 I/O 的函数之一。与 select 类似,poll 也允许进程监视多个文件描述符的状态,但它使用了一个 pollfd 结构体数组来跟踪文件描述符的状态。 相比于 selectpoll 没有文件描述符数量的限制,并且在某些情况下具有更好的性能,因为它不需要遍历整个文件描述符集合。然而,与 select 类似,poll 也是阻塞式的,需要等待直到某个文件描述符准备好。
  • epoll : epoll 是 Linux 上的一种高性能的多路复用机制,它是 selectpoll 的改进版本。epoll 使用了事件驱动的方式,允许进程在某个文件描述符准备好进行 I/O 操作时立即被通知,而不是像 selectpoll 那样需要轮询。 epoll 主要提供了三个系统调用:epoll_create 创建一个 epoll 实例,epoll_ctl 用于控制需要监听的文件描述符,以及 epoll_wait 用于等待事件的发生。 相比于 selectpollepoll 具有更好的性能和可扩展性,尤其在大量连接时,因为它避免了遍历整个文件描述符集合,而是在有活跃事件发生时立即通知进程。