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