LT和ET模式比较及实现

我前几个博客说过epoll支持ET工作模式,这种

有人可能会问,我们不是read/recv函数是阻塞的嘛,为啥修改文件描述符的文件状态来说明是非阻塞I/O呢?

其实read函数只是一个通用的读文件设备的接口,其是否阻塞需要由设备的属性(文件描述符)和设定(设置recv的参数)所决定。一般来说,读字符终端、网络的socket描述字,管道文件等,这些文件的文件状态默认都是阻塞的方式,如果是读磁盘上的普通文件,一般是非阻塞方式的。所以可以通过修改文件的状态(通过fcntl函数修改)来使得变为非阻塞I/O或者阻塞I/O(普通文件),当然你也可以在recv函数中的flag参数将其设定为MSG_DONTWAIT也可使其变为非阻塞I/O,这样当你读取的时候即非阻塞了,这两种方式都可以修改,只是修改的对象不同。(ps:对于管道文件或读字符中断等默认为阻塞的文件,其可以在open函数第二个参数直接设定O_NONBLOCK获取到非阻塞的文件描述符)

epoll 对文件的描述符的操作有两种模式 : LT(Level Trigger, 电平触发)模式 和 ET(Edge Trigger ,边沿触发)模式。LT模式是默认的工作模式,这个模式下epoll相当于一个效率较高的poll。当往epoll中内核事件表中注册EPOLLET事件时,epoll将以ET模式来操作该文件描述符。ET是epoll的高效模式。
        对于采用LT工作的文件描述符,当epolll_wait检测到其上有事件发生并将此事件通知应用程序后,应用程序可以不立即处理该事件。这样当应用程序下次调用epoll_wait时,epolll_wait还会再次向应用程序通知此事件,直到有该事件被处理。而对于采用ET模式的文件描述符,当epoll_wait检测当其上有事件发生时并将此事件通知应用程序后,应用程序必须立即处理该事件,因为后序的epolll_wait调用不再讲此事件通知应用程序,可见,ET模式在很大程度上降底了同一个epoll事件被重复触发的次数,因此效率要比LT模式高。

猜你喜欢

转载自blog.csdn.net/Eunice_fan1207/article/details/84891428