LT自动挡,ET手动挡(epoll)

LT自动挡,ET手动挡(epoll)

epoll有 ET和LT两种模式, 默认是LT模式。

LT模式的时候,epoll_wait 会把有事件的 file 再次加到 rdllist 列表中,以便下次epoll_wait可以再检查一遍。

            if (epi->event.events & EPOLLONESHOT)
                epi->event.events &= EP_PRIVATE_BITS;
            else if (!(epi->event.events & EPOLLET)) { //LT模式
                /*
                 * If this file has been added with Level
                 * Trigger mode, we need to insert back inside
                 * the ready list, so that the next call to
                 * epoll_wait() will check again the events
                 * availability. At this point, noone can insert
                 * into ep->rdllist besides us. The epoll_ctl()
                 * callers are locked out by
                 * ep_scan_ready_list() holding "mtx" and the
                 * poll callback will queue them in ep->ovflist.
                 */
                list_add_tail(&epi->rdllink, &ep->rdllist);
            } 

LT 模式下,状态不会丢失,程序完全可以于 epoll 来驱动。

ET模式下,程序首先要自己驱动逻辑,如果遇到 EAGAIN错误的时候,就要依赖epoll_wait来驱动,这时epoll帮助程序从阻碍中脱离。

 

所以LT是自动挡, ET是手动挡。 

 

ET 边沿触发的 边沿是 AGAIN错误,属于下降沿触发。

 

ET 的驱动事件依靠 socket的 sk_sleep 等待队列唤醒,这只有在有新包到来才能发生,数据包导致POLLIN, ACK确认导致 sk_buffer destroy从而导致POLLOUT, 但这不是一对一得关系,是多对一(多个网络包产生一个POLLIN, POLLOUT事件)。

 

 ET常见错误:

 recv到了合适的长度, 程序处理完毕后就epoll_wait

 这时程序可能长期阻塞,因为这时socket的 rev_buffer里还有数据,或对端close了连接,但这些信息都在上次通知了你,你没有处理完,就epoll_wait了

 正确做法是:

recv到了合适的长度, 程序处理; 再次recv, 若果是EAGAIN则epoll_wait。 

 

使用ET模式时, 程序自己驱动下,会发生socket被关闭的情况,这时要处理EPIPE信号和返回值。(如果不处理EPIPE那么会导致程序core掉) 

总结:ET 使用准则,只有出现EAGAIN错误才调用epoll_wait。

 

场景:短连接,短数据包(一个recv和send就可以完成所有的网络操作),这种情形下测试的结果是ET和LT一样的效率。(所以不要以为用了ET效率就有提高)

strace -c -fF ./your_prog 后得到信息是 epoll_ctl 消耗的时间比 recv+send 还多。 

总结原因:整个程序是以网络事件来驱动的,所以每个连接都要epoll_ctl 3次; 如果程序自己主动recv+send, 不行的时候再网络驱动的话,可以节省这些epoll_ctl开销。

 

对于长连接,大数据包应用,因为 LT模式只能设置当时感兴趣的事件(如果不写数据也设置POLLOUT的话,会导致cpu 100%) ,所以要频繁调用epoll_ctl,内核也要多次操作链表,所以效率会比ET模式低。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值