在关闭套接字之前,有必要从epoll中注销吗?

29
假设有以下代码,其中“sock”是之前已经在由epfd指定的epoll文件描述符中注册过的TCP套接字句柄。
epoll_ctl(epfd, EPOLL_CTL_DEL, sock, &ev);
close(sock);

如果套接字随后会被关闭,是否仍然需要调用 epoll_ctl?或者关闭套接字会自动解除注册吗?

1个回答

39

手册页面

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

A6 是的,但需要注意以下几点。 文件描述符是对打开的文件描述符的引用(请参见open(2))。每当一个描述符通过 dup(2),dup2(2),fcntl(2) F_DUPFDfork(2) 进行复制时,都会创建一个指向相同打开文件描述符的新文件描述符。只有在所有指向它的文件描述符已关闭后,打开的文件描述符才会继续存在。仅当所有指向基础打开文件描述符的文件描述符已关闭(或在使用 epoll_ctl(2) EPOLL_CTL_DEL 明确删除描述符之前)才会从 epoll 集合中删除文件描述符。这意味着即使已关闭作为 epoll 集合一部分的文件描述符,如果其他指向相同底层文件描述符的文件描述符仍保持打开状态,则仍可能报告该文件描述符的事件。


2
谢谢!我一直在查找答案,不停地使用“man epoll_ctl”、“man epoll_create”,但忘记了“man epoll”的摘要页面。 - selbie
所以只要没有使用dup()复制它,进程也没有分叉,你就没问题了? - MarkR
2
然而,事实似乎并非如此。我刚刚编写了一个简单的代码片段,创建了一个监听套接字,将其添加到 epoll 中,关闭了套接字,然后继续执行 epoll_wait。如果在此期间建立了连接并且删除成功,则会触发它。 - Tommi Kyntola
3
是的,如果你不使用 close() 函数来关闭文件描述符,显然它们就不会关闭。 - Will
@TommiKyntola:只是为了澄清一下,您是期望close()会移除已经添加到队列中的事件吗? - undefined
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接