epoll的LT和ET

https://www.jianshu.com/p/d3442ff24ba6

https://www.cnblogs.com/abelchao/p/11703795.html

ET
句柄在发生读写事件时只会通知用户一次
ET模式主要关注fd从不可用到可用或者可用到不可用的情况。
ET只支持非阻塞模式。

LT
只要句柄一直处于可用状态,就会一直通知用户。
LT模式下,句柄读缓冲区被读空后,句柄会从可用转变为不可以用,这个时候不会通知用户。写缓冲区只要还没写满,就会一直通知用户。
LT模式支持阻塞和非阻塞两种方式。epoll默认的模式是LT。
LT下,应用层的业务逻辑比较简单,更不容易遗漏事件,更不容易出错。通常,在将数据写完后,我们会关闭句柄的写事件。

LT模式下,可写状态的fd会一直触发事件,该怎么处理这个问题

  • 方法1:每次要写数据时,将fd绑定EPOLLOUT事件,写完后将fd同EPOLLOUT从epoll中移除。
  • 方法2:方法一中每次写数据都要操作epoll。如果数据量很少,socket很容易将数据发送出去。可以考虑改成:数据量很少时直接send,数据量很多时在采用方法1.

https://blog.csdn.net/peng314899581/article/details/78066374?utm_source=debugrun&utm_medium=referral
recv的写法
由于tcp是流,我们也不知道接收缓冲有多少个包,长度多少,所以我们可以用一个固定长度1024,每次取1k数据,直到把数据取完。边缘触发只能使用这种写法!
当使用水平触发模式的时候,我们读事件触发,可以取8k数据就走,不要在这一个读事件这里太久,不耽误后面事件的触发,反正读事件会后面一直触发,下次再取8k继续就好。但是如果是边缘模式,那么读事件触发,你一定要一次把数据全部取完,因为它只触发一次,这就是区别。

接收连接之后,会把连接对象丢给IO线程池,这个IO线程池一般线程数量等于cpu核数,这个IO线程池每个人都有自己的epoll,来监听连接对象的可读事件,(多线程使用epoll的安全原因我的另外一篇博客有写,从epoll源码分析它的使用)IO线程读完数据,会进行tcp的粘包,半包处理,然后封装成task,最后丢给一个工作线程池,工作线程池处理task,最后处理完task需要回复,就给一个专门的发送线程,这个发送线程统一发送数据,所以写事件用的少。

全部评论

相关推荐

投递腾讯等公司8个岗位
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务