EPOLLOUT | EPOLLET,虚假的wakups和MTU

时间:2014-01-28 01:14:38

标签: c++ asynchronous

写入程序使用带有固定缓冲区的多次写入发送几个MB(几乎没有延迟)。处理程序使用EPOLLOUT | EPOLLET标志注册。

  1. MTU = 16KB,写入缓冲区= 4KB或更多。从write(...)调用返回少量~3个EAGAIN(在下一个事件中重新开始写入)和~30个虚假的EPOLLOUT(在所有写入完成并且数据被认为发送之后)。
  2. MTU = 16KB,写入缓冲区= 2KB。几个~5个EAGAIN和一些(2-5个)虚假的EPOLLOUT事件 - 日志表明作者和读者在这种情况下同时进行。
  3. MTU = 16KB,写入缓冲器< 1KB。几个~5个EAGAIN和一个没有虚假的EPOLLOUT事件。
  4. MTU = 1-5KB,写入缓冲区= 4KB。几个~5个EAGAIN并且没有虚假的EPOLLOUT事件。
  5. MTU = 50KB(环回) - 99%的事件是虚假的EPOLLOUT。
  6. 这似乎并不那么简单 当缓冲区完全进入“可用空间”时,会生成EPOLLOUT。与MTU大小的相关性很有趣。 问题:

    1)除非最后一次写入以EAGAIN代码结束,否则禁用EPOLLOUT - 是正确的模式吗?

    2)更大的缓冲区或MTU建议传输更大的数据块 产生较少的TCP / IP缓冲区更新和较少的事件。实践表明相反。任何人都可以对此有所了解吗?

2 个答案:

答案 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),并且可以在使用后者的任何地方使用,因为它共享相同的语义

    
  

所以我对你问题的回答是:

  1. 是的,你是对的。

  2. 既然你知道你观察到了很多 LT EPOLLOUT,尽管你有 ET EPOLLOUT,也许你需要改变你的结论。

  3. 让我说明 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