ET、LT、EPOLLONESHOT

LT水平触发模式

  • epoll_wait检测到文件描述符有事件发生,则将其通知给应用程序,应用程序可以不立即处理该事件。

  • 当下一次调用epoll_wait时,epoll_wait还会再次向应用程序报告此事件,直至被处理。
    在这里插入图片描述

ET边缘触发模式

  • epoll_wait检测到文件描述符有事件发生,则将其通知给应用程序,应用程序必须立即处理该事件

  • 必须要一次性将数据读取完,使用非阻塞I/O,读取到出现eagain
    在这里插入图片描述

    • 为什么ET模式下需要使用非阻塞?
      • 每次通过 read 系统调用读取数据时,最多只能读取缓冲区大小的字节数;如果某个文件描述符一次性收到的数据超过了缓冲区的大小,那么需要对其 read 多次才能全部读取完毕
      • select 可以使用阻塞 I/O。通过 select 获取到所有可读的文件描述符后,遍历每个文件描述符,read 一次数据,这些文件描述符都是可读的,因此即使 read 是阻塞 I/O,也一定可以读到数据,不会一直阻塞下去。
      • select 采用水平触发模式,因此如果第一次 read 没有读取完全部数据,那么下次调用 select 时依然会返回这个文件描述符,可以再次 read
      • select 也可以使用非阻塞 I/O。当遍历某个可读文件描述符时,使用 for 循环调用 read 多次,直到读取完所有数据为止(返回 EWOULDBLOCK)。这样做会多一次 read 调用,但可以减少调用 select 的次数。
      • 在 epoll 的边缘触发模式下,只会在文件描述符的可读/可写状态发生切换时,才会收到操作系统的通知,因此,如果使用 epoll 的边缘触发模式,在收到通知时,必须使用非阻塞 I/O,并且必须循环调用 read 或 write 多次,直到返回 EWOULDBLOCK 为止,然后再调用 epoll_wait 等待操作系统的下一次通知。
      • 如果没有一次性读/写完所有数据,那么在操作系统看来这个文件描述符的状态没有发生改变,将不会再发起通知,调用 epoll_wait 会使得该文件描述符一直等待下去,服务端也会一直等待客户端的响应,业务流程无法走完。这样做的好处是每次调用 epoll_wait 都是有效的——保证数据全部读写完毕了,等待下次通知。在水平触发模式下,如果调用 epoll_wait 时数据没有读/写完毕,会直接返回,再次通知。因此边缘触发能显著减少事件被触发的次数。
      • 为什么 epoll 的边缘触发模式不能使用阻塞 I/O?很显然,边缘触发模式需要循环读/写一个文件描述符的所有数据。如果使用阻塞 I/O,那么一定会在最后一次调用(没有数据可读/写)时阻塞,导致无法正常结束。

EPOLLONESHOT

  • 一个线程读取某个socket上的数据后开始处理数据,在处理过程中该socket上又有新数据可读,此时另一个线程被唤醒读取,此时出现两个线程处理同一个socket

  • 我们期望的是一个socket连接在任一时刻都只被一个线程处理,通过epoll_ctl对该文件描述符注册epolloneshot事件,一个线程处理socket时,其他线程将无法处理,当该线程处理完后,需要通过epoll_ctl重置epolloneshot事件

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值