水平触发和边缘触发

epoll既支持水平触发也支持边缘触发,默认是水平触发。


水平触发(LT)

当被监控的文件描述符上有可读写事件发生时,会通知用户程序去读写,他会一直通知用户,如果这个描述符是用户不关心的,它每次都返回通知用户。

读缓冲区不为空时, 读事件触发。写缓冲区不为满时, 写事件触发。

水平触发时,逻辑简单,不太容易出bug。

写数据时,LT模式需要先打开EPOLLOUT,当没有数据需要写出时,再关闭EPOLLOUT(否则会一直返回EPOLLOUT事件)。


边缘触发(ET)

当被监控的文件描述符上有可读写事件发生时,会通知用户程序去读写,它只会通知用户进程一次,这需要用户一次把内容读取完。如果用户一次没有读完数据,再次请求时,不会立即返回,需要等待下一次的新的数据到来时才会返回,这次返回的内容包括上次未取完的数据。

读缓冲区状态变化时, 读事件触发。写缓冲区状态变化时, 写事件触发。(只会提示一次)

边缘触发时,业务上层处理的逻辑较为复杂,处理不当存在丢失事件的风险。

写数据时,ET模式可以便捷地处理EPOLLOUT事件,省去打开与关闭EPOLLOUT的epoll_ctl(EPOLL_CTL_MOD)调用。


区别

水平触发和边缘触发的区别:实质上是调度策略

例如,两条线分别有数据ABC、DEF,水平触发的处理顺序ADBECF,边缘触发的处理顺序ABCDEF。


选择

nginx使用边缘触发。redis使用边水平触发。为什么?

如果server的响应通常较小,不会触发EPOLLOUT,那么适合使用LT,例如redis等。

而nginx作为高性能的通用服务器,网络流量可以跑满达到1G,这种情况下很容易触发EPOLLOUT,则使用ET。

listenfd建议使用LT,connfd看情况选择,一般用LT即可,流量大的场景使用ET。

posted @ 2022-05-09 10:38  天下太平  阅读(804)  评论(0编辑  收藏  举报