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

福哥答案2020-08-22:

select,poll,epoll 都是 操作系统实现 IO 多路复用的机制。 我们知道,I/O 多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是 读就绪或者写就绪),能够通知程序进行相应的读写操作。那么这三种机制有什 么区别呢。
1、支持一个进程所能打开的最大连接数
select:单个进程所能打开的最大连接数有 FD_SETSIZE 宏定义,其大 小是 32 个整数的大小(在 32 位的机器上,大小就是 3232,同 理 64 位机器上 FD_SETSIZE 为 3264),当然我们可以对进行修改, 然后重新编译内核,但是性能可能会受到影响。
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() 模型即支持水平触发,也支持边缘触发,默认是水平触发。


评论

猜你喜欢

转载自blog.csdn.net/weixin_48502062/article/details/108175620