编写程序使用带有固定缓冲区的多次写入发送一些MBs (几乎没有延迟)。处理程序使用EPOLLOUT | EPOLLET标志注册。
write(...)调用返回的几个EAGAIN (写入在下一个事件中重新启动)和~30个伪EPOLLOUT (毕竟写入完成,数据被认为是发送的)。EPOLLOUT似乎并不那么简单,因为EPOLLOUT是在缓冲区从full生成到“一些可用空间”时生成的。与MTU大小的相关性是有趣的。问题:
1)禁用EPOLLOUT,除非最后一次写入以EAGAIN代码结尾--是正确的模式吗?
2)较大的缓冲区或MTU建议在较少的TCP/IP缓冲区更新和较少的事件中传输较大的数据块。实际情况正好相反。有谁能解释一下这件事吗?
发布于 2014-01-28 01:27:08
EPOLLOUT表示缓冲区中有空间。这并不意味着仅仅是从没有空间到某种空间的过渡。您只应该在从发送中获得EAGAIN之后才使用它。否则,您只会得到一个毫无意义的EPOLLOUT事件流,因为发送缓冲区中几乎总是有空间。
是的,这是正确的使用方法。只需写到你得到EAGAIN,然后使用EPOLLIUT告诉你什么时候你可以再写。
发布于 2014-01-28 01:51:59
您似乎混淆了epoll的两种用法。关键概念是“水平触发(LT)”和“边缘触发(ET)”。
man 7 epoll声明:
使用EPOLLET标志的应用程序应该使用非阻塞文件描述符,以避免阻塞、读或写需要处理多个文件描述符的任务。建议使用epoll作为边缘触发(EPOLLET)接口的方法如下: I具有非阻塞文件描述符;以及 通过等待事件后才读(2)或写(2)返回EAGAIN。 相反,当用作级别触发接口(默认情况下,未指定EPOLLET )时,epoll只是一个更快的轮询(2),并且可以在使用后者的地方使用,因为它具有相同的语义。
所以我对你的问题的回答是:
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 LThttps://stackoverflow.com/questions/21395074
复制相似问题