select、poll、epoll 的区别?

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

select 单个进程所能打开的最大连接数有 FD_SETSIZE 宏定义,其大小是 32个整数的大小(在 32 位的机器上,大小就是 3232,同理 64 位机器上FD_SETSIZE 为 3264),当然我们可以对进行修改,然后重新编译内核, 但是性能可能会受到影响。
poll poll 本质上和 select 没有区别,但是它没有最大连接数的限制,原因是它是基于链表来存储的
epoll 虽然连接数基本上只受限于机器的内存大小

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 低效是因为每次它都需要轮询。但低效也是相对的,视情况而定,也可通过良好的设计改善。