2013-11-26 112 views
1

我正在使用多线程嵌入式应用程序,其中epoll在其中一个线程中用于IO。我依赖epoll的一个特殊功能,它指定关闭一个文件描述符会自动将它从epoll集中移除(man 7 epoll中的Question/Answer 6)。在这种情况下,文件描述符关闭在调用epoll_wait的同一个线程中完成。结果发生的是epoll_wait在关闭文件描述符后返回一个事件,并且程序最终崩溃,因为它试图访问当文件描述符关闭时解除分配的资源。据我所知,文件描述符在任何地方都没有,尽管我不知道如何验证它。我知道有一个事实,即没有拨打fork()dup(),dup2()fcntl()与特定的dup选项。这个特定的文件描述符是用EPOLLOUT,EPOLLIN,EPOLLERREPOLLHUP登记的。它是电平触发的。有没有人知道这个功能的任何警告?手册页是否有误?任何有用的信息可以帮助我进一步调试该问题?我知道我可以从集合中删除文件描述符,但我想知道为什么会发生这种情况。Epoll_wait在关闭的文件描述符上返回事件

+0

epoll_wait为该文件描述符返回的事件是EPOLLIN,EPOLLHUP和EPOLLERR。 – duffsterlp

+0

您可以使用[strace](http://linux.die.net/man/1/strace)来验证您的程序是否在执行您认为正在执行的操作。你能在一个简单的单线程测试程序中重现这种行为吗? –

回答

2

关闭一个文件描述符似乎并没有将它从epoll中移除。我在3.12.2上用一个非常简单的例子试了一下。我倾向于将该手册页称为错误或不准确。

我在测试做了什么:

  • 创建TCP套接字
  • 束缚,为localhost:5555
  • 设置它来听
  • 创建了一个epoll的
  • 添加的插座有hup,err和
  • 睡了一下,所以我可以选择使用nc连接
  • 关闭套接字
  • epoll_wait
  • epoll_ctl德尔
  • 清理

等待工作,即使插座已被关闭我是否已经连接到这一点。

编辑:The epoll_ctl_del如果套接字已关闭,则确实失败。在阅读了当前的手册页之后,看起来他们确实没问题。 epoll页面指向选择(2)关于关闭被监视的套接字,并且该页面表示行为未指定。

+0

为了记录,我在一个服务器上做了什么,当一个连接被关闭时,我明确地将它从epoll中删除(并且实际上标记了epoll以重新等待它刚刚从epoll_wait中出来,这是运行在另一个线程),然后继续关闭并销毁相关资源。 –

+0

epoll_ctl del在你的例子中工作的事实是高度可疑的。套接字未关闭或者已被复制。我们可以看到代码吗? –

+0

找到了代码。果然,'epoll_ctl_del'确实失败了。我为我的测试程序制作了“doclose”标志,以检查epoll等待返回值是否在关闭套接字的情况下进行,并且我必须在没有关闭的情况下从运行中获取“del工作”,当然它的工作原理。 –

相关问题