我正在使用一个多线程嵌入式应用程序,其中 epoll 用于其中一个线程中的 IO。我依赖于 epoll 的一个特定功能,该功能指定关闭文件描述符会自动将其从 epoll 集中删除(man 7 epoll 中的问题/答案 6)。在这种情况下,文件描述符关闭是在调用 epoll_wait
的同一个线程中完成的。最终发生的事情是 epoll_wait
在文件描述符关闭后返回一个事件,程序最终崩溃,因为它试图访问在文件描述符关闭时被释放的资源。据我所知,文件描述符没有在任何地方被欺骗,尽管我不知道如何验证这一点。我知道没有调用 fork()
、dup()
、dup2()
或 fcntl( )
使用特定的 dup 选项。这个特定的文件描述符在 EPOLLOUT
、EPOLLIN
、EPOLLERR
和 EPOLLHUP
中注册。它是电平触发的。是否有人知道此功能的任何注意事项?手册页不正确吗?有什么有用的信息可以帮助我进一步调试问题吗?我知道我可以从集合中删除文件描述符,但我想知道为什么会这样。
最佳答案
关闭文件描述符似乎并没有将其从 epoll 中删除。我在 3.12.2 上用非常简单的例子试过了。我倾向于称手册页错误或不准确。
我在测试中所做的是:
- 创建了一个 TCP 套接字
- 将它绑定(bind)到 localhost:5555
- 让它听
- 创建了一个 epoll
- 用 hup、err 和 in 添加套接字
- 睡了一会儿,所以我可以选择与 nc 连接
- 关闭套接字
- epoll_wait
- epoll_ctl 删除
- 打扫干净
即使套接字已关闭,无论我是否连接到它,等待仍然有效。
编辑:如果套接字已关闭,epoll_ctl_del
会失败。在阅读了当前的手册页之后,似乎它们实际上没问题。 epoll 页面指向 select(2) 关于关闭被监视的套接字,该页面表示该行为未指定。
关于c++ - Epoll_wait 在关闭的文件描述符上返回事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20222079/