面试题答案
一键面试1. epoll的LT(水平触发)和ET(边缘触发)模式
1.1 LT(水平触发)模式工作原理
- 当文件描述符对应的读缓冲区中有数据可读(即缓冲区不为空),或者写缓冲区中有可写空间(即缓冲区未满)时,epoll_wait 会将该文件描述符通知给用户程序。
- 用户程序可以在任意时刻从该文件描述符读取数据或者向其写入数据,只要条件满足,epoll_wait 就会持续通知。
1.2 ET(边缘触发)模式工作原理
- 当文件描述符的状态发生变化,即从不可读变为可读,或者从不可写变为可写时,epoll_wait 会触发一次通知。
- 一旦触发通知后,用户程序必须尽可能多地读取或写入数据,直到读缓冲区为空或者写缓冲区满,否则后续可能不会再次收到通知。这就要求用户程序在收到 ET 模式的通知后,要采用非阻塞 I/O 进行操作。
1.3 性能表现
- LT模式:实现相对简单,适合初学者。但由于只要条件满足就持续通知,可能会导致一些不必要的系统调用,在高并发场景下,如果连接数众多且每个连接的 I/O 操作不是非常频繁,可能会增加系统开销。
- ET模式:性能更高,因为它减少了不必要的通知,只在状态变化时触发。在高并发且每个连接 I/O 操作频繁的场景下,能显著减少系统调用次数,提高效率。但由于需要非阻塞 I/O 配合,实现相对复杂,对编程要求较高。
1.4 应用场景
- LT模式:适用于对性能要求不是极致,而更注重开发效率和简单性的场景,例如一些小型服务器或者测试环境。
- ET模式:适用于对性能要求极高的高并发场景,如大型的网络服务器、游戏服务器等,这些场景下连接数多且 I/O 操作频繁。
2. epoll比select和poll更适合处理大量并发连接的原因
2.1 监视文件描述符数量限制
- select:能监视的文件描述符数量有限,通常受限于 FD_SETSIZE,一般为 1024。在高并发场景下,连接数很容易超过这个限制。
- poll:理论上没有文件描述符数量的限制,但实际上由于需要将所有监视的文件描述符集合传递给内核,随着文件描述符数量增加,内存开销和系统调用时间会显著增加。
- epoll:没有文件描述符数量的限制,它通过一个 epoll 句柄管理所有监视的文件描述符,内核为每个注册的文件描述符维护一个红黑树,大大提高了管理效率。
2.2 事件通知方式
- select:采用轮询方式检查所有文件描述符,不管是否有事件发生,每次调用 select 都需要遍历所有监视的文件描述符集合,时间复杂度为 O(n),在高并发时效率极低。
- poll:同样采用轮询方式,与 select 类似,时间复杂度也是 O(n),随着文件描述符数量增加,性能会急剧下降。
- epoll:采用回调机制,当有事件发生时,内核将事件添加到就绪列表中,epoll_wait 只需要检查就绪列表,时间复杂度为 O(1),在高并发场景下性能优势明显。
2.3 内存拷贝
- select 和 poll:每次调用都需要将用户空间的文件描述符集合拷贝到内核空间,返回时又将内核空间的结果拷贝回用户空间,随着文件描述符数量增加,内存拷贝开销增大。
- epoll:通过 epoll_ctl 注册文件描述符到内核空间后,后续的事件通知不需要再次拷贝,只需要从内核空间获取就绪列表,减少了内存拷贝开销。