我们的生产代码中存在长期存在的错误。这本质上是一个基于套接字的守护进程。它使用select来监听一堆文件描述符。
偶尔(每天一次左右),选择将返回EBADF。
我已编写代码来搜索错误的文件描述符,它会遍历每个fd并调用select。这些调用永远不会返回EBADF。我也试过fstat。他们也永远不会回归EBADF。
我还重写了守护进程以使用民意调查。这没有用。
有没有人有其他想法? (除了我犯了一个愚蠢的错误,这对于选择很容易)。
答案 0 :(得分:4)
最有可能在已关闭的文件描述符上调用select
。
通常的来源是重用fd_set
而不重新初始化它。
你在信号处理程序中有什么事吗? (比如在HUP上重新打开日志文件?)
答案 1 :(得分:4)
我同意詹姆斯的观点。使用poll(),您可以轻松检查每个fd的事件。
即
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 ...
当然,你不会在现实世界中以那种方式实现它,它只是一个例子。很久以前我停止使用select(),poll()是一个更好的界面。你是对的,用select()来拍摄自己很容易。
答案 2 :(得分:3)
如果您使用poll(),那么您可以浏览数据并查找哪个fd失败,这是最大的优势。