面试题答案
一键面试优势
- 连接数限制:
- select 受限于操作系统文件描述符数量限制(通常为 1024),poll 理论上无连接数限制,但实际应用中也会因内存等因素受限。而 epoll 基于内核实现,在 Linux 系统下可支持大量连接,能轻松处理数万甚至数十万的并发连接。
- 性能:
- select 和 poll 每次调用都需要将文件描述符集合从用户态拷贝到内核态,且在返回时需要遍历整个文件描述符集合来获取就绪的文件描述符,时间复杂度为 O(n)。epoll 通过 epoll_ctl 只在添加、修改、删除文件描述符时进行一次拷贝,并且使用事件驱动机制,通过 epoll_wait 返回就绪的文件描述符,时间复杂度为 O(1),在高并发场景下性能更优。
- 使用便捷性:
- select 接口中,对于可读、可写、异常事件等需要分别设置文件描述符集合,使用相对复杂。poll 虽然改进了一些,但也不够简洁。epoll 使用一个 epoll_event 结构体来管理所有事件,使用相对简单方便。
原理
- 数据结构:
- epoll 在内核中维护了一颗红黑树来管理用户添加的文件描述符,这样在添加、删除、查找文件描述符时时间复杂度为 O(logn)。同时还维护了一个就绪链表,用于存储就绪的文件描述符。
- 工作模式:
- epoll 有两种工作模式:LT(水平触发)和 ET(边缘触发)。
- LT 模式:只要文件描述符对应的设备处于就绪状态,每次 epoll_wait 调用时都会通知应用程序该文件描述符就绪。
- ET 模式:只有当文件描述符对应的设备状态从非就绪变为就绪时,epoll_wait 才会通知应用程序,这种模式下应用程序需要及时处理就绪事件,否则可能错过事件通知,但其在高并发场景下能减少不必要的通知,提高效率。
- epoll 有两种工作模式:LT(水平触发)和 ET(边缘触发)。
- 事件通知:
- 当文件描述符状态发生变化时,内核会将其加入到就绪链表中,epoll_wait 调用时直接从就绪链表中获取就绪的文件描述符并返回给用户态,避免了像 select 和 poll 那样遍历所有文件描述符,从而提高了效率。