select
本质上是通过设置和轮询fd_set
来检查是否有就绪的文件描述符,其缺点在于:
select
都需要把fd_set
从用户空间拷贝到内核空间,文件描述符较多时开销较大;select
都需要线性扫描fd_set
,文件描述符较多时开销较大。
poll
与select
相似,不同之处在于poll
使用pollfd
链表结构保存文件描述符,因此与select
相比,没有文件描述符数量的限制。
epoll
提供了三个函数:
epoll_create
用于创建一个epoll
句柄;epoll_ctl
用于注册要监听的事件类型,其特点是:
epoll
句柄中时,会把所有的文件描述符拷贝进内核空间,保证了每个文件描述符在整个过程中只拷贝一次,不会出现重复拷贝;epoll_wait
用于等待事件的发生,唤醒等待中的进程;
epoll
对文件描述符的操作有两种模式:
epoll_wait
检测到描述符事件发生并将此事件通知应用程序,应用程序可以不立即处理该事件,下次调用epoll_wait
时,将会再次响应应用程序并通知此事件;epoll_wait
检测到描述符事件发生并将此事件通知应用程序,应用程序必须立即处理该事件,如果不处理,下次调用epoll_wait
时,不会再次响应应用程序并通知此事件;
需要注意的是,表面上看epoll
的性能最好,但是连接数量较少并且都十分活跃的情况下,select
和poll
的性能可能较好,因为epoll
的通知机制需要使用回调函数。