Epoll:它会默默地删除fds吗?

时间:2017-10-28 07:23:13

标签: c linux-kernel epoll libev

我一直在阅读libev's source code并偶然发现了这条评论:

  

a)epoll默默地从fd集中删除fds。因为没有告诉我们fd已被删除,否则我们必须不断“重新安置”我们怀疑可能已经改变的fds(与kqueue相同的问题,但那里的成本要低得多)。

我在一些现代的Linux内核上用epoll(直接使用系统调用)进行了一些测试,我无法重现它。我没有看到“默默地消失fds”的任何问题。有人可以详细说明这个并告诉我它是否仍然是一个问题?

1 个答案:

答案 0 :(得分:3)

这是一个相当含糊的文本,但我想只是如果描述符在其他地方close d,它会被静默地从集合中删除。从Linux联机帮助页epoll(7)

  

Q6 关闭文件描述符会导致它              从所有epoll集中自动删除?

     

A6 是的,但请注意以下几点。一份文件              descriptor是对打开文件的引用              描述(见open(2))。每当一个描述符              通过dup(2)dup2(2)fcntl(2)复制              F_DUPFDfork(2),新的文件描述符引用 -              戒指到相同的打开文件描述是cre-              ated。打开文件描述继续              存在直到引用它的所有文件描述符              已经关闭。删除文件描述符              从epoll设置后只有所有文件              描述符引用底层的打开文件              描述已被关闭(或之前,如果              描述符是使用显式删除的              epoll_ctl(2) EPOLL_CTL_DEL)。这意味着              甚至在作为文件描述符的一部分之后              epoll set已关闭,可能会报告事件              对于该文件描述符,如果其他文件描述 -              tors引用相同的底层文件              描述仍然开放。

所以你有一个fd 42的套接字。它得到close d,然后从epoll对象中删除。但是内核没有通过 libev通知epoll_wait关于此的内容。现在,使用fd = epoll_modify再次调用42epoll_modify不知道此文件描述符42是否与epoll对象中已有的文件描述符相同,或者是否重用了文件描述符编号为42的其他文件描述。

还有人可能会说这些评论只是咆哮而且libev API的设计在这里是错误的。