彻底搞懂ET与LT,另外还有TinyWebServer中的一点小问题

https://yq.aliyun.com/articles/495842?spm=a2c4e.11153940.0.0.61cf4d40BBz2x2

首先上转帖,这篇文章讲的很透彻了。

ET与LT触发的区别:

红线:fd状态改变是才会触发。那么什么情况会导致fd状态的改变呢?

对于读取操作:

(1) 当buffer由不可读状态变为可读的时候,即由空变为不空的时候。

(2) 当有新数据到达时,即buffer中的待读内容变多的时候。

对于写操作:

(1) 当buffer由不可写变为可写的时候,即由满状态变为不满状态的时候。

(2) 当有旧数据被发送走时,即buffer中待写的内容变少得时候。

蓝线:fd的events中有相应的时间(位置1)即会触发。那么什么情况下会改变events的相应位呢?

对于读操作:

(1) buffer中有数据可读的时候,即buffer不空的时候fd的events的可读为就置1。

对于写操作:

(1) buffer中有空间可写的时候,即buffer不满的时候fd的events的可写位就置1。

说明:红线是时间驱动被动触发,蓝线是函数查询主动触发。

总结一下:

对于ET模式,它的触发方式是转帖链接图中的红线部分,也就是说:

ET下,对于监听读取操作:

(1) 当buffer由不可读状态变为可读的时候,即由空变为不空的时候。

(2) 当有新数据到达时,即buffer中的待读内容变多的时候

(3) 当buffer中有数据可读(即buffer不空)且用户对相应fd进行epoll_mod IN事件时

 (1),(2)很好理解,特别对于(3):

EPOLL_CTL_MOD相当于重新修改了该sockfd对应的需要监视的事件,尽管在下一轮中可读数据并未增长,但仍然会提醒该事件发生。

对于写操作:

(1) 当buffer由不可写变为可写的时候,即由满状态变为不满状态的时候。

(2) 当有旧数据被发送走时,即buffer中待写的内容变少得时候。

(3) 当buffer中有可写空间(即buffer不满)且用户对相应fd进行epoll_mod OUT事件时。

其中3与上面一样。

对于LT模式:

ET模式相当于是LT模式的子集,除了上述ET模式的情况外,以下也会进行通知。

这篇转帖写的实在是非常好,值得通读。

另外关于这个TinyWebServer:

有一点小问题:

在向socket中写时:

在遇到写缓冲区满而返回EAGAIN时,返回状态为STATUS_WRITE。

而在主函数中:

它对于STATUS_WRITE的处理却是直接将该sockfd remove掉,也就是说默认了遭遇EAGAIN就相当于已经写完。

这个逻辑是不是有问题,如果说出现:

写缓冲区已满,但写入数据仍为写完的情况,在这个情况下将socket remove掉是不对的,是不是应该不对它remove,而应该等到下次epoll_wait检测到该sockfd可写后继续写入,而又应用层来判断是否写完数据后,return一个success标识,再进行remove才更好呢?

当然,作者是不是考虑到对一个静态页面来说,写缓冲区写满但文件扔未写完的情况不存在呢?

原文地址:https://www.cnblogs.com/lxy-xf/p/11198111.html