epoll的ET和LT触发方式

epoll,select,poll触发方式概述

对于select和poll两种IO复用机制来说,默认都只有一种事件触发机制那就是LT水平触发,对于epoll来说则是有两种事件触发方式,一种是LT水平触发,另外一种就是ET边缘触发,ET边缘触发其效率更高,编程实现难度较大.下面就两种事件触发方式就一个深入的介绍.

LT水平触发

对于水平触发来说,要明白其触发的条件是对理解LT模式的前提,对于LT事件触发来说,只有当出现高电平的时候才会触发事件,那么现在只要搞懂什么是高电平,什么是低电平,就可以知道LT模式下的触发方式.可读事件,我们称之为EPOLLIN,可写事件我们称之为EPOLLOUT,下面就两种事件触发方式进行描述:

EPOLLIN事件发生的条件:

  • 内核输入缓冲区为空  低电平
  • 内核输入缓冲区不为空  高电平

高电平的时候触发EPOLLIN事件,如果没有把缓冲区的数据读取完,下次还会触发的,因为始终是高电平

EPOLLOUT事件发生的条件:

  • 内核发送缓冲区不满 高电平
  • 内核发送缓冲区满 低电平

高电平的时候触发EPOLLOUT事件,所以在一开始的时候不要关注EPOLLOUT时间,因为发送缓冲区是不满的所以会导致CPU忙等待,每次都触发。

什么时候关注EPOLLOUT事件呢? 当write的时候没有写完全,因为发送缓冲区满了,这个时候才关注EPOLLOUT事件直到下次把所有数据都发送完毕了,才取消EPOLLOUT事件

ET边缘触发

ET模式又称之为边缘触发,只有在上升沿或者下降沿的时候才会触发,何为上升沿和下降沿呢,也就是出现低电平到高电平或者高电平到低电平的转换的时候才会触发事件.

EPOLLIN事件发生的条件:

  • 有数据到来(输入缓冲区初始为空,为低电平,有数据到来变成了高电平)

EPOLLout事件发生的条件:

  • 内核发送缓冲区不满(当发送缓冲区出现满之后为低电平,然后内核发送出去了部分数据后变成了不满,也就是高电平)

对于ET模式来说,一开始就应该关注EPOLLLIN和EPOLLOUT事件EPOLLIN事件到来,说明输入缓冲区是有数据了(由低电平(初始为空是低电平)到高电平了),那么就可以调用read来读取数据了但是读取数据的时候需要注意,必须读取到出现EAGAIN为止,否则如果数据没读完,那么此时处于高电平,下次再来数据仍然是高电平.EPOLLOUT事件到来说明发送缓冲区由满到不满了了(也就是由高电平(发送缓冲区为满)到低电平了),那么这个时候可以调用write来写数据了,但是写数据需要注意的是,你需要将剩下没有发送完的数据发送完,或者发送到出现EAGAIN错误。为什么呢,如果你不把剩下的数据发送完,那么会导致剩下的数据被延迟发送了,谁知道下次是什么时候触发呢(需要再次把缓冲区写满,然后内核发送了部分,这个时候才会再次产生EPOLLOUT事件),或者是发送直到出现EAGAIN错误,这表明发送缓冲区又满了。所以下次只要发送缓冲区不满就会再次触发EPOLLOUT事件了。