水平触发与边缘触发


Network

水平触发(level-trggered)

边缘触发(edge-triggered)

  • 只要文件描述符关联的读内核缓冲区非空,有数据可以读取,就一直发出可读信号进行通知,
  • 当文件描述符关联的内核写缓冲区不满,有空间可以写入,就一直发出可写信号进行通知

边缘触发(edge-triggered)

  • 当文件描述符关联的读内核缓冲区由空转化为非空的时候,则发出可读信号进行通知,
  • 当文件描述符关联的内核写缓冲区由满转化为不满的时候,则发出可写信号进行通知

两者的区别?

水平触发是只要读缓冲区有数据,就会一直触发可读信号,而边缘触发仅仅在空变为非空的时候通知一次,

  1. 读缓冲区刚开始是空的
  2. 读缓冲区写入 2KB 数据
  3. 水平触发和边缘触发模式此时都会发出可读信号
  4. 收到信号通知后,读取了 1kb 的数据,读缓冲区还剩余 1KB 数据
  5. 水平触发会再次进行通知,而边缘触发不会再进行通知

所以边缘触发需要一次性的把缓冲区的数据读完为止,也就是一直读,直到读到 EGAIN(EGAIN 说明缓冲区已经空了)为止,因为这一点,边缘触发需要设置文件句柄为非阻塞。

EAGAIN Resource temporarily unavailable (may be the same value as EWOULDBLOCK) (POSIX.1-2001).

非阻塞模式就是读写函数会立即获取当前数据后返回,而不会等数据的到来。

边缘触发效率更高,但是要求读取数据时使用非阻塞的方式一直把数据读完

epoll 支持水平出发和边缘触发 select 只支持水平触发