前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2020-08-22:I/O多路复用中select/poll/epoll的区别?

2020-08-22:I/O多路复用中select/poll/epoll的区别?

原创
作者头像
福大大架构师每日一题
修改2020-08-24 10:10:41
3110
修改2020-08-24 10:10:41
举报

福哥答案2020-08-22:

select,poll,epoll 都是 操作系统实现 IO 多路复用的机制。 我们知道,I/O 多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是 读就绪或者写就绪),能够通知程序进行相应的读写操作。那么这三种机制有什 么区别呢。

1、支持一个进程所能打开的最大连接数

select:单个进程所能打开的最大连接数有 FD_SETSIZE 宏定义,其大 小是 32 个整数的大小(在 32 位的机器上,大小就是 32*32,同 理 64 位机器上 FD_SETSIZE 为 32*64),当然我们可以对进行修改, 然后重新编译内核,但是性能可能会受到影响。

poll:poll 本质上和 select 没有区别,但是它没有最大连接数的限 制,原因是它是基于链表来存储的。

epoll:虽然连接数有上限,但是很大,1G 内存的机器上可以打开 10 万左右的连接,2G 内存的机器可以打开 20 万左右的连

2、FD 剧增后带来的 IO 效率问题

select:因为每次调用时都会对连接进行线性遍历,所以随着 FD 的 增加会造成遍历速度慢的“线性下降性能问题”。

poll:同上。

epoll因为 epoll 内核中实现是根据每个 fd 上的 callback 函数来实 现的,只有活跃的 socket 才会主动调用 callback,所以在活跃 socket 较少的情况下,使用 epoll 没有前面两者的线性下降的性能 问题,但是所有 socket 都很活跃的情况下,可能会有性能问题。

3、 消息传递方式

select:内核需要将消息传递到用户空间,都需要内核拷贝动作 。

poll:同上。

epoll:epoll 通过内核和用户空间共享一块内存来实现的。

总结:

综上,在选择 select,poll,epoll 时要根据具体的使用场合以及这三种方式 的自身特点。

1、表面上看 epoll 的性能最好,但是在连接数少并且连接都十分活跃的情况 下,select 和 poll 的性能可能比 epoll 好,毕竟 epoll 的通知机制需要很多函数回调。

2、select 低效是因为每次它都需要轮询。但低效也是相对的,视情况而定, 也可通过良好的设计改善。

补充知识点:

Level_triggered(水平触发):当被监控的文件描述符上有可读写事件发生时, epoll_wait()会通知处理程序去读写。如果这次没有把数据一次性全部读写完(如 读写缓冲区太小),那么下次调用 epoll_wait()时,它还会通知你在上没读写完的 文件描述符上继续读写,当然如果你一直不去读写,它会一直通知你!!!如果 系统中有大量你不需要读写的就绪文件描述符,而它们每次都会返回,这样会大 大降低处理程序检索自己关心的就绪文件描述符的效率!!!

Edge_triggered(边缘触发):当被监控的文件描述符上有可读写事件发生时, epoll_wait()会通知处理程序去读写。如果这次没有把数据全部读写完(如读写缓 冲区太小),那么下次调用 epoll_wait()时,它不会通知你,也就是它只会通知你 一次,直到该文件描述符上出现第二次可读写事件才会通知你!!!这种模式比 水平触发效率高,系统不会充斥大量你不关心的就绪文件描述符!!

select(),poll()模型都是水平触发模式,信号驱动 IO 是边缘触发模式,epoll() 模型即支持水平触发,也支持边缘触发,默认是水平触发。

***

[评论](https://user.qzone.qq.com/3182319461/blog/1598050790)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档