610 字
3 分钟
select、poll 和 epoll 有什么区别
  1. 1操作系统面试学习路线与知识地图
  2. 2什么是用户态和内核态
  3. 3什么是系统调用?它和普通函数调用有什么区别
  4. 4进程和线程有什么区别
  5. 5进程的五种状态:新建、就绪、运行、阻塞与终止
  6. 6fork、exec 和 wait 分别做什么
  7. 7什么是竞态条件和临界区?如何保证互斥
  8. 8互斥锁和自旋锁有什么区别?分别适合什么场景
  9. 9死锁的四个必要条件是什么?如何逐个预防
  10. 10缺页异常如何处理?虚拟内存不等于 Swap
  11. 11阻塞、非阻塞、同步、异步 I/O 怎么区分
  12. 12抢占式调度是什么?SJF 和 MLFQ 适合什么假设
  13. 13进程间通信如何选择?管道、共享内存、信号和 Socket
  14. 14线程切换时,操作系统要做哪些操作
  15. 15进程上下文切换要保存什么?为什么有开销
  16. 16死锁是什么?如何预防和避免死锁?
  17. 17银行家算法如何避免死锁?死锁检测后怎样恢复
  18. 18活锁、饥饿和死锁有什么区别
  19. 19进程调度算法:FCFS、SJF、优先级、时间片轮转与多级反馈队列
  20. 20调度指标有哪些?什么是优先级反转
  21. 21为什么要有虚拟内存
  22. 22TLB、多级页表和虚拟地址转换是怎么工作的
  23. 23什么是分段,什么是分页
  24. 24页面置换算法有哪些?FIFO、LRU 和 Clock
  25. 25信号量是什么?计数信号量和二元信号量怎么用
  26. 26条件变量是什么?为什么要和互斥锁配合使用
  27. 27进程间通信方式:管道、消息队列、共享内存、信号量与套接字
  28. 28I/O 模型有哪些:阻塞、非阻塞与多路复用
  29. 29select、poll 和 epoll 有什么区别本文
  30. 30epoll 的 LT 和 ET 模式有什么区别
  31. 31什么是异步 I/O?它和非阻塞、多路复用的区别
  32. 32什么是僵尸进程和孤儿进程?如何处理
  33. 33原子操作是什么?原子性、可见性和有序性有什么区别
  34. 34什么是工作集和抖动?内存不足时为何系统变慢
  35. 35mmap 是什么?文件映射和匿名映射怎么理解
  36. 36什么是写时复制?fork 和私有映射如何利用 COW

select、poll、epoll 都用于等待多个文件描述符就绪。它们报告的是可进行某种 I/O 的状态,应用仍要调用 read/write;在非阻塞套接字上尝试读写仍需正确处理 EAGAIN、部分读写和连接关闭。

select 使用位图表达关注集合。每次调用需要传入并返回集合,用户态与内核态之间要复制和扫描;描述符数量通常受 FD_SETSIZE 等限制,具体限制取决于 libc 和系统配置。调用后集合内容会变化,程序需要重新建立集合。

poll 用数组描述关注项,避免 select 位图接口的固定集合大小限制,但每次等待仍需传入描述符数组并扫描关注项,连接总量大时成本会随集合规模增长。

epoll 是 Linux 专有接口,通过创建 epoll 实例、注册关注项,再等待就绪事件。注册与等待分离,内核维护关注集合;在大量连接但每次只有少数活跃时,通常避免每轮把全部集合重新复制扫描。不过它不是“任何负载下都是 O(1)”或必然更快:活跃连接很多、事件处理很重、注册管理成本高时,结果依场景而变。epoll 也不可移植到所有类 Unix 平台。

三者的可读/可写只说明某些操作当前可能进行;例如 TCP 可读也可能意味着对端关闭、错误或只读到部分数据。监听套接字可读常表示有连接可接受。边缘触发模式还要求程序持续处理到 EAGAIN,否则可能错过后续通知。

常见追问#

Q:为什么高并发 Linux 服务常选 epoll?
A:当连接数大且每轮活跃比例低时,注册复用并只处理就绪事件可减少重复扫描全部描述符的成本;仍需按实际负载评估。

Q:select 的描述符上限是 1024 吗?
A:常见 libc 的 FD_SETSIZE 默认值可能为 1024,但不能把它当所有系统、所有编译方式的固定内核上限;应查目标环境接口定义和限制。

Q:epoll 返回可读就能一次读完吗?
A:不能保证。TCP 是字节流,read 可能只返回部分数据;应用需循环读取或维护缓冲区,并遵守触发模式要求。

select、poll 和 epoll 有什么区别
https://blog.xqcherry.top/posts/interview/operating-system/select-poll-epoll/
作者
xqcherry
发布于
2026-10-12
许可协议
CC BY-NC-SA 4.0