select/poll/epoll优缺点及应用场景

简介: select/poll/epoll优缺点及应用场景


  1. select
  • 优点:
  • 跨平台性好,几乎所有的操作系统都支持 select
  • 简单易用,接口简洁,易于理解和上手。
  • 缺点:每次调用select后,内核会清除集合中未就绪的文件描述符,不会保存,每次调用select前都要重新设置一次集合
  • 效率较低,select 在处理大量文件描述符时性能下降明显,因为它采用线性扫描的方式来遍历文件描述符集合
  • select 调用需要传入 fd 数组,每次调用select需要拷贝一份到内核,每次调用select前都要重新将fd加入文件描述符集合中,因为事件发生后,文件描述符集合将被内核修改,高并发场景下这样的拷贝消耗的资源是惊人的。
  • select 在内核层仍然是通过遍历的方式检查文件描述符的就绪状态,是个同步过程,只不过无系统调用切换上下文的开销。
  • select 仅仅返回可读文件描述符的个数,具体哪个可读还是要用户自己遍历。
  • 对于大量的文件描述符,需要维护大型的数据结构,会带来额外的开销。
  • 文件描述符集合的大小有限制,通常为 FD_SETSIZE,1024,在一些系统中可能会受到限制。
  1. poll
  • 优点:
  • 跨平台性好,几乎所有的操作系统都支持 poll
  • select 更加灵活,没有文件描述符集合大小的限制。
  • 对于大量的文件描述符,性能相对较好,因为 poll 使用链表来管理文件描述符,遍历开销相对较小。
  • 缺点:
  • 在大量文件描述符的情况下,性能仍然有限,因为每次调用 poll 都需要将所有的文件描述符从用户空间复制到内核空间,然后再从内核空间复制回来。
  1. epoll
  • 优点:
  • 高性能,适用于大量的并发连接,因为 epoll 使用了红黑树来管理文件描述符,可以快速定位到就绪事件。
  • 内核中保存一份文件描述符集合(红黑树结构),无需用户每次都重新传入,只需进行增删改即可。
  • 内核不再通过轮询的方式找到就绪的文件描述符,而是通过异步 IO 事件唤醒。
  • 支持水平触发和边缘触发两种模式,边缘触发模式下只会触发一次就绪事件,避免了反复触发事件的开销。
  • 内核仅会将有 IO 事件的文件描述符返回给用户,用户也无需遍历整个文件描述符集合。
  • 没有文件描述符集合的大小限制,可以处理大量的并发连接。
  • 缺点:
  • 不能跨平台,epoll 是 Linux 特有的 API,不太容易移植到其他操作系统上。
  • 使用较为复杂,相比于 selectpollepoll 的接口更加底层,需要更多的编程技巧和经验。

应用场景

很容易产生一种错觉认为只要用 epoll 就可以了,select 和 poll 都已经过时了,其实它们都有各自的使用场景。

select 应用场景

select 的 timeout 参数精度为微秒,而 poll 和 epoll 为毫秒,因此 select 更加适用于实时性要求比较高的场景,比如核反应堆的控制。

select 可移植性更好,几乎被所有主流平台所支持。

poll 应用场景

poll 没有最大描述符数量的限制,如果平台支持并且对实时性要求不高,应该使用 poll 而不是 select。

epoll 应用场景

只需要运行在 Linux 平台上,有大量的描述符需要同时轮询,并且这些连接最好是长连接。

需要同时监控小于 1000 个描述符,就没有必要使用 epoll,因为这个应用场景下并不能体现 epoll 的优势。

需要监控的描述符状态变化多,而且都是非常短暂的,也没有必要使用 epoll。因为 epoll 中的所有描述符都存储在内核中,造成每次需要对描述符的状态改变都需要通过 epoll_ctl() 进行系统调用,频繁系统调用降低效率。并且 epoll 的描述符存储在内核,不容易调试。

目录
相关文章
|
5月前
|
安全 物联网 5G
5g技术的优缺点是什么
5g技术的优缺点是什么
568 0
|
10天前
|
Java Linux 应用服务中间件
【编程进阶知识】高并发场景下Bio与Nio的比较及原理示意图
本文介绍了在Linux系统上使用Tomcat部署Java应用程序时,BIO(阻塞I/O)和NIO(非阻塞I/O)在网络编程中的实现和性能差异。BIO采用传统的线程模型,每个连接请求都会创建一个新线程进行处理,导致在高并发场景下存在严重的性能瓶颈,如阻塞等待和线程创建开销大等问题。而NIO则通过事件驱动机制,利用事件注册、事件轮询器和事件通知,实现了更高效的连接管理和数据传输,避免了阻塞和多级数据复制,显著提升了系统的并发处理能力。
25 0
|
5月前
|
存储 安全 Java
【深度挖掘Java并发编程底层源码】「底层技术原理体系」带你零基础认识和分析学习相关的异步任务提交机制FutureTask的底层原理
【深度挖掘Java并发编程底层源码】「底层技术原理体系」带你零基础认识和分析学习相关的异步任务提交机制FutureTask的底层原理
39 0
|
4月前
|
消息中间件 存储 监控
实战Linux I/O多路复用:借助epoll,单线程高效管理10,000+并发连接
本文介绍了如何使用Linux的I/O多路复用技术`epoll`来高效管理超过10,000个并发连接。`epoll`允许单线程监控大量文件描述符,显著提高了资源利用率。文章详细阐述了`epoll`的几个关键接口,包括`epoll_create`、`epoll_ctl`和`epoll_wait`,以及它们在处理并发连接中的作用。此外,还探讨了`epoll`在高并发TCP服务场景的应用,展示了如何通过`epoll`和线程/协程池来构建服务框架。
496 8
|
4月前
|
区块链 决策智能 UED
目前Layer2 解决方案有什么优缺点
目前Layer2 解决方案有什么优缺点
58 1
|
5月前
|
消息中间件 缓存 Java
【多线程学习】深入探究定时器的重点和应用场景
【多线程学习】深入探究定时器的重点和应用场景
113 1
|
5月前
|
消息中间件 存储 监控
【ZeroMQ的SUB视角】深入探讨订阅者模式、C++编程实践与底层机制
【ZeroMQ的SUB视角】深入探讨订阅者模式、C++编程实践与底层机制
708 1
|
5月前
|
并行计算 API 计算机视觉
Python多线程与多进程:概念、区别及应用场景解析
Python多线程与多进程:概念、区别及应用场景解析
242 0
|
存储 缓存 算法
提升性能的利器:理解线程池的使用、工作原理和优势
在Java中,创建和销毁线程开销较大,为了避免线程过多而带来使用上的开销。 所以我们需要对线程进行统一管理及复用,这就是我们要说的线程池。
|
存储 缓存 安全
[并发编程] - 操作系统底层工作原理
[并发编程] - 操作系统底层工作原理
137 0