选择EBADF:哪个FD不好?

use*_*425 12 c linux

我们的生产代码中存在长期存在的错误.这本质上是一个基于套接字的守护进程.它使用select监听一堆文件描述符.

偶尔(每天一次左右),选择将返回EBADF.

我编写了代码来搜索错误的文件描述符,它遍历每个fd并调用select.这些调用永远不会返回EBADF.我也试过fstat.他们也永远不会回归EBADF.

我还重写了守护进程以使用民意调查.这没有用.

有没有人有其他想法?(除了我犯了一个愚蠢的错误,这一切都很容易与选择).

Nik*_*sov 5

最有可能的select是在关闭的文件描述符上调用它。通常的来源是重用fd_set而不重新初始化它。你的信号处理程序中有什么事情发生吗?(比如重新打开 HUP 上的日志文件?)


小智 4

我同意詹姆斯的观点。使用 poll(),您可以轻松检查每个 fd 的 revents。

IE

struct pollfd fds[NUM_FDS];
int ret, i;

...

ret = poll(fds, NUM_FDS, POLL_TIMEOUT);
for (i = 0; i < NUM_FDS; i++)
  if (fds[i].revents & POLLHUP || fds[i].revents & POLLNVAL)
     ... do something ...
Run Code Online (Sandbox Code Playgroud)

当然,在现实世界中你不会这样实现它,这只是一个例子。我很久以前就停止使用 select() 了,poll() 是一个更好的接口。你是对的,使用 select() 太容易搬起石头砸自己的脚了。