IO多路复用select,poll,epoll的区别
文章目录
select
, poll
, 和 epoll
都是用于处理多路输入输出(IO)的系统调用,它们允许程序监视多个文件描述符(FDs),等待一个或多个FDs成为非阻塞的,即准备好进行IO操作(如读或写)。这些机制在网络编程中尤其有用,用于实现高效的并发服务器。
以下是对每个系统调用的简要说明:
select
select
系统调用允许程序监视一组文件描述符,以等待其中一个或多个FDs准备好执行IO操作,通过轮询的方式捕获io事件
它有几个限制,包括FD集合大小的限制(通常是1024)。
它使用固定大小的文件描述符集合,导致随着监控的FD数量增加,其效率降低。
|
|
poll
poll 提供了与 select 类似的功能,但是没有文件描述符数量的限制。通过轮询的方式捕获io事件 poll 使用 pollfd 结构数组来跟踪每个文件描述符。 相比 select,poll 的扩展性更好,但是随着FD数量增加,性能仍然会下降。
|
|
epoll
epoll 是Linux特有的,它解决了 select 和 poll 在扩展性上的问题,通过操作系统的事件通知机制,回调函数的方式来实现异步的I/O操作. epoll 可以处理大量的FDs,因为它工作方式不同,只关心活跃的FDs。 使用 epoll_create 创建一个epoll实例,然后通过 epoll_ctl 添加、修改或删除文件描述符,最后使用 epoll_wait 等待事件。
|
|
epoll的事件触发方式
epoll
提供了两种触发模式:边缘触发(Edge-Triggered)
和水平触发(Level-Triggered)
。
- 边缘触发(Edge-Triggered)模式:
当文件描述符上的状态发生变化时,epoll 会通知应用程序,但只通知一次,即只在状态从未就绪变为就绪时通知。 如果应用程序没有处理完所有就绪事件,下次调用 epoll_wait 时只会返回新的就绪事件,不会返回之前已经就绪但没有处理的事件。 边缘触发模式适用于需要及时处理所有就绪事件的场景,可以减少事件通知的次数。
- 水平触发(Level-Triggered)模式:
当文件描述符上的状态处于就绪状态时,epoll 会通知应用程序,并在该状态保持就绪时不断通知。 即使应用程序没有处理就绪事件,下次调用 epoll_wait 时仍然会返回之前已经就绪但没有处理的事件。 水平触发模式适用于需要持续监控文件描述符状态变化的场景,可以方便地实现非阻塞 I/O 操作。
总结
select
和 poll
更为通用,但随着监视的FD数量增加,效率降低。
epoll
只在Linux上可用,但提供了更好的性能,尤其是在处理大量FDs时。它也支持一些额外的特性,如边缘触发(ET)和水平触发(LT)模式。
文章作者 bobo
上次更新 2024-01-18