写入程序使用带有固定缓冲区的多次写入发送几个MB(几乎没有延迟)。处理程序使用EPOLLOUT | EPOLLET
标志注册。
write(...)
调用返回少量~3个EAGAIN(在下一个事件中重新开始写入)和~30个虚假的EPOLLOUT(在所有写入完成并且数据被认为发送之后)。这似乎并不那么简单 当缓冲区完全进入“可用空间”时,会生成EPOLLOUT。与MTU大小的相关性很有趣。 问题:
1)除非最后一次写入以EAGAIN代码结束,否则禁用EPOLLOUT - 是正确的模式吗?
2)更大的缓冲区或MTU建议传输更大的数据块 产生较少的TCP / IP缓冲区更新和较少的事件。实践表明相反。任何人都可以对此有所了解吗?
答案 0 :(得分:1)
EPOLLOUT表示缓冲区中有空格。它并不仅仅意味着从无空间到某个空间的过渡。您只应在从发送中获得EAGAIN后才能使用它。否则你只会获得无意义的EPOLLOUT事件流,因为发送缓冲区中几乎总是有空格。
你的(1),是的,这是使用它的正确方法。只要写一下,直到你得到EAGAIN,然后用EPOLLIUT告诉你何时可以再写一次。
答案 1 :(得分:0)
您似乎混淆了epoll
的两种用法。关键概念是“水平触发( LT )”和“边缘触发( ET )”。
man 7 epoll
州:
使用EPOLLET标志的应用程序应使用非阻塞文件描述符,以避免阻塞读取或写入处理多个文件描述符的任务。将epoll用作边缘触发(EPOLLET)接口的建议方法如下:
我使用非阻塞文件描述符;和
ii仅在读取(2)或写入(2)之后等待事件返回EAGAIN。相比之下,当用作级别触发的接口时(默认情况下,当未指定EPOLLET时),epoll只是一个更快的轮询(2),并且可以在使用后者的任何地方使用,因为它共享相同的语义
所以我对你问题的回答是:
是的,你是对的。
既然你知道你观察到了很多 LT EPOLLOUT
,尽管你有 ET EPOLLOUT
,也许你需要改变你的结论。
让我说明 ET 和 LT 之间的区别。
Buf=Empty
V ET
Buf=Avail LT
V
Buf=Avail LT
V
Buf=Avail LT
V
Buf=Empty
V ET
Buf=Avail LT