java nio的select和linux的epoll区别
java nio的select和linux的epoll的区别:selector是多路复用器,它是java nio的一个核心组件,提供了询问通道是否已经准备好执行每个I/O操作的能力;而epoll是Linux内核中的IO多路复用的机制,是对于select和poll的性能提升。
1.java nio的select
selector是java nio的核心组件之一,可以翻译为多路复用器,它可以同时监控多个通道的IO(输入输出)状况。从底层来看,Selector提供了询问通道是否已经准备好执行每个I/O操作的能力。Selector允许单线程处理多个Channel。仅用单个线程来处理多个Channels的好处是,只需要更少的线程来处理通道。事实上,可以只用一个线程处理所有的通道,这样会大量的减少线程之间上下文切换的开销。
2.linux的epoll
epoll是Linux内核中的一种可扩展IO事件处理机制,即IO多路复用的机制。它较早在Linux 2.5.44内核中引入,可被用于代替POSIX select和 poll系统调用,并且在具有大量应用程序请求时能够获得较好的性能。此时被监视的文件描述符数目非常大,与旧的select和 poll系统调用完成操作所需 O(n)不同, epoll能在O(1)时间内完成操作,所以性能相当高。此外,epoll 与 FreeBSD的kqueue类似,都向用户空间提供了自己的文件描述符来进行操作。
延伸阅读
select、poll和epoll有什么区别
select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。select、poll和epoll有以下两个区别:
1.性能上的区别
select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在epoll_wait中进入睡眠的进程。
虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。
2.成本上的区别
select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次;而epoll只要一次拷贝,而且把current往等待队列上挂也只挂一次,这也能节省不少的开销。
在epoll_wait的开始,注意上述的等待队列并不是设备等待队列,只是一个epoll内部定义的等待队列。

