EPOLL 的 LT和ET-学习笔记

Epoll一般有两种方式边缘触发(ET)和水平触发(LT)

epoll 默认模式是水平触发

  • 水平触发: 只要满足条件,就触发事件(只要内核缓冲区中的数据没有读完,就会一直触发)
  • 边缘触发: 每当状态发生变化的时候就触发一个事件.
  • 举一个例子,你在吃一碗饭,LT当你没有吃完这碗饭,它会一直给你提示,ET 当你去打第二碗饭的时候,才会给你提示.

LT相当于一个快速的poll,可读可写就绪条件和poll是一样的.
ET在使用的过程中,建议:

  • 设置非阻塞IO
  • 只有当read或者write 返回EAGAIN的时候,才调用下一次epoll_wait.
  • 在应用层可以维护一个列表,防止有一个文件描述符号有大量的输入,非阻塞IO可能导致一直处理它,其他就绪文件描述符处于处于饥饿状态.

LT和ET相比不容易遗漏事件,会一直提醒

ET为什么要和非阻塞IO进行搭配

  • 因为边缘触发只有当IO事件发生的时候,我们才会收到通知,在另外一个IO事件到来的时候,我们不会收到任何新的通知,我们不知道我们每次需要处理多少IO,所以我们每次需要尽可能的多读,如果使用阻塞IO一直读,在最后一次读取的时候,就会发生阻塞现象,所以要使用非阻塞IO,直到返回相应的系统调用返回EAGIN/EWOULDBLOCK
  • 如果send 数据过大,阻塞式IO就会阻塞了.(socket发送缓冲区放不下,send只负责数据拷贝到socket缓冲区,拷贝完立即返回.)

解决当某一个文件描述符有大量输入,不间断的输入流,让非阻塞IO可能导致一直处理它,其他就绪文件描述符处于饥饿状态:

我们可以维护一个列表,列表中存放已经被通知就绪的文件描述符,通过循环按照如下方式处理
1.我们可以调用epoll_wait 监视文件描述符,并将就绪态的描述符添加到table中去,如果文件描述符已经注册到table中去,那么这次监视的时间应该设置为较小值或者0,这样如果没有新的文件描述符成为就绪态,应用程序就可以迅速进行下一步,去处理已经处于就绪态的文件描述符号.
2. 在table 中,只有那些已经注册为就绪态的文件描述符上进行一定限度的IO操作,当相关的非阻塞IO调用出现EAGIN/EWOULDBLOCK时,可以从列表中移除.

epoll为什么比select高效

  • select 在调用的时候都需要将所要监控的fd从用户态传递给内核态,epoll只拷贝一次即可,挂载到eventpoll上的红黑树之上.
  • epoll 是基于事件驱动的,给每一个fd上注册了一个回调函数,select则需要通过遍历去寻找发生事件的fd.
  • select的文件描述符的大小为FD_SETSIZE,由内核决定,epoll的文件描述符号大小比select高很多.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值