前言
最近在学习nginx的原理,发现我对于select,poll与epoll并不是很熟悉,因此,特地研究下它们的区别。
正文
- select与poll的区别
- select,poll与epoll的区别
select其实就是轮询的意思,把需要监听的对象注册到内核,然后调用select去轮询,有IO事件就调handler处理;但是,select只是查询内核的数据是否准备好,也就是内核缓冲区的数据;后续还得把内核缓冲区的数据拷贝到用户空间。而且select只支持1024个文件描述符。
- I/O多路复用就是通过一种机制,一个进程可以监视多个描述符
- poll的基本原理与select类似,只是没有文件描述符数量的限制,但是数量过大时,会影响性能
- epoll只需要以下的三个系统函数调用:epoll_create(2), epoll_ctl(2), epoll_wait(2)。
- epoll对文件描述符的操作有两种模式:LT(level trigger)和ET(edge trigger)。LT模式是默认模式,LT模式与ET模式的区别如下:
LT模式:当epoll_wait检测到描述符事件发生并将此事件通知应用程序,应用程序可以不立即处理该事件。下次调用epoll_wait时,会再次响应应用程序并通知此事件。
ET模式:当epoll_wait检测到描述符事件发生并将此事件通知应用程序,应用程序必须立即处理该事件。如果不处理,下次调用epoll_wait时,不会再次响应应用程序并通知此事件。
1 . LT模式
LT(level triggered)是缺省的工作方式,并且同时支持block和no-block socket.在这种做法中,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你的。
2 . ET模式
ET(edge-triggered)是高速工作方式,只支持no-block socket。在这种模式下,当描述符从未就绪变为就绪时,内核通过epoll告诉你。然后它会假设你知道文件描述符已经就绪,并且不会再为那个文件描述符发送更多的就绪通知,直到你做了某些操作导致那个文件描述符不再为就绪状态了(比如,你在发送,接收或者接收请求,或者发送接收的数据少于一定量时导致了一个EWOULDBLOCK 错误)。但是请注意,如果一直不对这个fd作IO操作(从而导致它再次变成未就绪),内核不会发送更多的通知(only once)
ET模式在很大程度上减少了epoll事件被重复触发的次数,因此效率要比LT模式高。epoll工作在ET模式的时候,必须使用非阻塞套接口,以避免由于一个文件句柄的阻塞读/阻塞写操作把处理多个文件描述符的任务饿死。