1.select没有将文件描述符和事件绑定,,仅仅是一个文件描述符的集合,因此select分为三种不同类型参数分别传入不同的事件。这一方面使得select不能处理更多类型的事件,另一方面由于fd_set集合的在线修改,应用程序下次调用select前不得不重置这三个fd_set集合。
poll则把文件描述符和事件都定义在一个结构体pollfd中,任何事件都被统一处理并且内核每次修改的是revents成员,events成员保持不变。因此下次调用poll时应用程序无需重置pollfd类型事件集的参数。
select和poll调用返回的是整个用户注册事件的集合,
epoll通过在内核中维护一个内核事件表,并通过一个独立的系统调用epoll_ctl来控制对内核事件表的插入删除和修改。这样每次epoll_wait调用都直接从内核事件表中取得用户注册的事件,无需反复读出。epoll_wait系统调用的events参数仅用来返回就绪的事件,这使得应用程序索引就绪文件描述符的时间复杂度为O(1)
2.poll和epoll分别用nfds和maxevents参数指定最多监听多少个文件描述符和事件,这两个数值都能打到系统允许打开的最大文件描述符数目即65535,而select一般只有1024
3.select和poll都只能工作在相对低效的LT模式,而epoll可以工作在ET高效模式,而且epoll还支持EPOLLONESHOT事件,能进一步减少读、写、异常事件的触发次数。
4.select与poll都采用轮询 的方式,将文件描述符拷贝到内核中,有关注的事件发生时全部轮询查找发生事件的描述符,而epoll_wait不同它采用的是回调的方式。内核检测到就绪的文件描述符时就会触发回调函数将该文件描述符上对应的事件插入内核就绪事件队列。内核最后在适当的时机将该就绪事件队列中的内容拷贝到用户空间。因此epollwait无需轮询整个文件描述符集合来检测哪些事件已经就绪。
5.当连接数目较大时,epoll效率不见得比select和poll高,因为此时回调函数被触发的过于频繁。