多路复用是同步非阻塞I/O,及Synchronous I/O Multiplexing,它是利用单独的线程(内核级)统一检测所有Socket,一旦某个Socket有了I/O数据,则启动相应的Appllication处理,在select和poll中利用轮询socket句柄的方式来实现检测socket中是否有I/O数据达到,这种方式开销,epoll等则改进了这种方式,利用底层notify机制,即Reactor方式来检测,Java NIO也采用这种机制。其实多路复用还是阻塞的(这个阻塞并非以上定义的阻塞,这里指Scoket无I/O数据时还是被wait,此外当使用select函数copy I/O数据入Application Buffer时,Application还是被阻塞的)
select和epoll区别:
1、每次调用select ,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大。
2.同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大。
3.select支持的文件描述符数量太小了,默认是1024。
poll:它没有最大连接数的限制,原因是它基于链表来存储的,但是同样有一个缺点:大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是否有意义。
4.epoll为每个fd指定一个回调函数,当设备就绪,唤醒等待队列上的等待者时,就会调用这个回调函数。
5.epoll所支持的fd上限是最大可以打开文件的数目。