epoll的ET和LT模式触发场景

epoll有两种事件模型:
Level Triggered (LT) 水平触发
socket接收缓冲区不为空,有数据可读,读事件一直触发
socket发送缓冲区不满,可以继续写入数据,写事件一直触发
Edge Triggered (ET) 边缘触发
socket的接收缓冲区状态变化时触发读事件
socket的发送缓冲区状态变化时触发写事件
总结:
水平触发:只要可读,就一直触发读事件,只要可写,就一直触发写事件
边缘触发:从不可读变为可读,从可读变为不可读,从不可写变为可写,从可写变为不可写,都只触发一次

水平触发:

1.从accept成功之后,可写事件就会一直触发,直到发送缓冲区满了。对方给你发送了数据,只要你的接收缓冲区还有数据没取完就会一直触发可读事件。

2.当对方断开连接,不管是主动断开还是异常断开,都会触发可读可写事件。为什么?因为你recv和send的时候都会给你返回(主动断开0,异常断开-1)。

关于epoll的触发和fd的状态:

读事件触发,写事件触发和可读,可写要分开。比如说读事件的触发告诉我们有数据可读,但是可读只是说我们读不会阻塞,会有返回,并不代表能成功读到数据。就像断开连接,触发了可读,我们去recv了确实没有阻塞,还给了我们返回“数据”,立即出错告诉我们断开了。

边缘触发:

1.从不可读变为可读:从接收缓冲区为空,到接收到数据后触发一次

2.从可读变为不可读:断开连接,从可读变为不可读触发一次

3.从不可写变为可写:从accept建立连接触发一次

4.从可写变为不可写:断开连接,从可写变为不可写触发一次

这里有一个很有意思的地方,当你对fd注册了可读可写事件时,每次可读事件触发都会给你顺便带上一个可写事件出来。比如说场景1,接收到对方数据了,触发了可读可写事件,虽然触发的原因是可读,但是此时fd的状态是可读可写,还是准确了反应此时fd的状态。

如果你只注册可写事件,那么就只有2,3和4场景会触发,2和4雷同。如果你注册了可读可写,那么4个场景都会有可写事件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章