浅谈select,poll和epoll的区别

简介: 云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! select,poll和epoll其实都是操作系统中IO多路复用实现的方法。 select select方法本质其实就是维护了一个文件描述符(fd)数组,以此为基础,实现IO多路复用的功能。

云栖号资讯:【点击查看更多行业资讯】
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!


select,poll和epoll其实都是操作系统中IO多路复用实现的方法。

select

select方法本质其实就是维护了一个文件描述符(fd)数组,以此为基础,实现IO多路复用的功能。这个fd数组有长度限制,在32位系统中,最大值为1024个,而在64位系统中,最大值为2048个,这个配置可以调用

1

来查看

select方法被调用,首先需要将fd_set从用户空间拷贝到内核空间,然后内核用poll机制(此poll机制非IO多路复用的那个poll方法,可参加附录)直到有一个fd活跃,或者超时了,方法返回。

int select(int maxfdpl, fd_set readfds, fd_set writefds, fd_set exceptfds, struct timeval timeout);
  • 如果返回值为-1,表明发生了错误
  • 如果返回值为0,表明超时了
  • 如果返回值为正数,表明有n个fd准备就绪了

select方法返回后,需要轮询fd_set,以检查出发生IO事件的fd。这样一套下来,select方法的缺点就很明显了:

  • fd_set在用户空间和内核空间的频繁复制,效率低
  • 单个进程可监控的fd数量有限制,无论是1024还是2048,对于很多情景来说都是不够用的。
  • 基于轮询来实现,效率低

poll

2

poll本质上和select没有区别,依然需要进行数据结构的复制,依然是基于轮询来实现,但区别就是,select使用的是fd数组,而poll则是维护了一个链表,所以从理论上,poll方法中,单个进程能监听的fd不再有数量限制。但是轮询,复制等select存在的问题,poll依然存在

epoll

epoll就是对select和poll的改进了。它的核心思想是基于事件驱动来实现的,实现起来也并不难,就是给每个fd注册一个回调函数,当fd对应的设备发生IO事件时,就会调用这个回调函数,将该fd放到一个链表中,然后由客户端从该链表中取出一个个fd,以此达到O(1)的时间复杂度

epoll操作实际上对应着有三个函数:epoll_create,epoll_ctr,epoll_wait

epoll_create

epoll_create相当于在内核中创建一个存放fd的数据结构。在select和poll方法中,内核都没有为fd准备存放其的数据结构,只是简单粗暴地把数组或者链表复制进来;而epoll则不一样,epoll_create会在内核建立一颗专门用来存放fd结点的红黑树,后续如果有新增的fd结点,都会注册到这个epoll红黑树上。

epoll_ctr

另一点不一样的是,select和poll会一次性将监听的所有fd都复制到内核中,而epoll不一样,当需要添加一个新的fd时,会调用epoll_ctr,给这个fd注册一个回调函数,然后将该fd结点注册到内核中的红黑树中。当该fd对应的设备活跃时,会调用该fd上的回调函数,将该结点存放在一个就绪链表中。这也解决了在内核空间和用户空间之间进行来回复制的问题。

epoll_wait

epoll_wait的做法也很简单,其实直接就是从就绪链表中取结点,这也解决了轮询的问题,时间复杂度变成O(1)

所以综合来说,epoll的优点有:

  • 没有最大并发连接的限制,远远比1024或者2048要大。(江湖传言1G的内存上能监听10W个端口)
  • 效率变高。epoll是基于事件驱动实现的,不会随着fd数量上升而效率下降
  • 减少内存拷贝的次数

水平触发和边缘触发

简单理解下

水平触发的意思就是说,只要条件满足,对应的事件就会一直被触发。所以如果条件满足了但未进行处理,那么就会一直被通知

边缘触发的意思就是说,条件满足后,对应的事件只会被触发一次,无论是否被处理,都只会触发一次。

而对于select和poll来说,其触发都是水平触发。而epoll则有两种模式:·EPOLLLT和EPOLLET

  • EPOLLLT(默认状态):也就是水平触发。在该模式下,只要这个fd还有数据可读,那么epoll_wait函数就会返回该fd
  • EPOLLET(高速模式):也就是边缘触发。在该模式下,当被监控的fd上有可读写事件发生时,epoll_wait会通知程序去读写,若本次读写没有读完所有数据,或者甚至没有进行处理,那么下一次调用epoll_wait时,也不会获取到该fd。这种效率比水平触发的要高,系统中不会充斥着大量程序不感兴趣的fd,不感兴趣直接忽视就行,下次不会再触发

总结:

  • select,poll是基于轮询实现的,将fd_set从用户空间复制到内核空间,然后让内核空间以poll机制来进行轮询,一旦有其中一个fd对应的设备活跃了,那么就把整个fd_set返回给客户端(复制到用户空间),再由客户端来轮询每个fd的,找出发生了IO事件的fd
  • epoll是基于事件驱动实现的,加入一个新的fd,会调用epoll_ctr函数为该fd注册一个回调函数,然后将该fd结点注册到内核中的epoll红黑树中,当IO事件发生时,就会调用回调函数,将该fd结点放到就绪链表中,epoll_wait函数实际上就是从这个就绪链表中获取这些fd。
  • epoll分为EPOLLLT(水平触发,默认状态)和EPOLLET(边缘触发,效率高)
  • 并不是所有的情况中epoll都是最好的,比如当fd数量比较小的时候,epoll不见得就一定比select和poll好

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/live

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-05-30
本文作者:JAYICE
本文来自:“掘金”,了解相关信息可以关注“掘金”

相关文章
|
自然语言处理 Kubernetes 机器人
基于OpenIM 实现聊天机器人功能
基于OpenIM 实现聊天机器人功能
1047 0
|
Linux 编译器 vr&ar
linux交叉编译一些常用依赖库util-linux,zlib,sqlite3,eudev ,openssl,libpng,glibc
linux交叉编译一些常用依赖库util-linux,zlib,sqlite3,eudev ,openssl,libpng,glibc
1082 1
|
9月前
|
人工智能 安全 机器人
2026年阿里云一键部署OpenClaw保姆级教程,快速拥有专属AI助理!
想拥有写周报、查资料、跑脚本的专属AI助理?只需一台阿里云服务器,按这篇保姆级教程操作,30分钟即可完成开源AI代理平台OpenClaw的部署!本地优先、支持多工具联动,7×24小时在线,新手友好。
717 5
|
SQL 缓存 关系型数据库
如何解决MySQL 的深度分页问题?
在构建高性能Web应用程序时,数据库查询性能至关重要。本文深入探讨了MySQL中`LIMIT ... OFFSET ...`语法的性能瓶颈,并介绍了一种更高效的分页方法——游标分页(Cursor Pagination)。通过记录每页最后一个记录的唯一标识,游标分页能显著提升查询效率,将时间复杂度从O(n + m)降低到O(log n + m),特别适用于大规模数据的分页查询场景。此外,文章还介绍了其他优化方法,如覆盖索引分页、分区表、缓存和基于时间戳的分页,并提供了实践中的最佳建议,帮助开发者选择最适合的分页策略,提升系统性能和用户体验。
1407 9
|
机器学习/深度学习 人工智能 监控
2000 张人脸眼部检测数据集 | 标注规范、数据划分与应用场景
本 人脸眼部检测数据集(2000 张图片已划分、已标注),以中小规模的精细化标注为核心,兼顾多样性与实用性,能够满足从学术研究到工程落地的多种需求。无论是初学者进行深度学习实验,还是科研人员做算法对比,抑或企业在产品开发阶段进行原型验证,该数据集都能提供坚实的数据支撑。
|
机器学习/深度学习 自然语言处理 监控
13_命名实体识别:精准提取文本中的关键信息
在当今信息爆炸的时代,人们每天需要处理海量文本数据。如何从这些非结构化文本中高效地提取关键信息,成为了自然语言处理(NLP)领域的核心挑战之一。命名实体识别(Named Entity Recognition,简称NER)技术正是解决这一问题的关键技术,它能够自动识别并分类文本中的人名、地名、组织机构名、时间、日期、金额等具有特定含义的实体。
2748 0
|
存储 自然语言处理 机器人
基于的Qwen模型的智能客服Discord机器人,使用🐫 CAMEL、SambaNova、Firecrawl和Qdrant实现RAG Agent
基于Qwen模型的智能客服Discord机器人,使用CAMEL、SambaNova、Firecrawl和Qdrant实现RAG Agent。构建了一个能够处理复杂问题并能进行快速响应的强大聊天机器人。该机器人可在Discord平台上运行,支持实时对话和语义搜索,提供准确、全面的回答。项目包含详细的安装步骤、代码示例及集成指南,适合开发者快速上手。
1362 36
|
人工智能 语音技术
ModuleNotFoundError: AutomaticSpeechRecognitionPipeline: No module named ‘funasr‘
这篇文章描述了在运行阿里语音AI模型的语音识别时遇到的`ModuleNotFoundError: No module named ‘funasr’`错误,并提供了通过`pip install funasr --upgrade -f https://modelscope.oss-cn-beijing.aliyuncs.com/releases/repo.html`命令重新安装funasr模块的解决方法。
ModuleNotFoundError: AutomaticSpeechRecognitionPipeline: No module named ‘funasr‘