在Linux中,期望fd < 最大开放文件描述符数量是合理的吗?

5

我正在编写一个需要处理多个打开的套接字(socket)的服务器,因此我使用setrlimit()函数(在特权降低之前作为root用户)来设置最大文件描述符数。以下是示例代码:

#include <sys/resource.h>
#define MAX_FD_C 9001

if (setrlimit(
      RLIMIT_NOFILE, &(struct rlimit){.rlim_cur = MAX_FD_C, .rlim_max = MAX_FD_C}
    ) == -1) {
    perror("Failed to set the maximum number of open file descriptors");
    return EXIT_FAILURE;
}

现在,我意识到可能不会有任何保证,并且我完全取决于Linux内核使用实现文件描述符表的方法;但是在实践中,假设此程序从Linux内核接收的任何fd值都小于我上面设置的MAX_FD_C,这是否合理?我希望尽可能紧凑地保留每个套接字数据,这可能意味着仅使用像 static struct client clients[MAX_FD_C] = {{0}}; 这样的数组,并将fd用作客户端结构的索引(这基本上是我自己版本的FDT)。

1
是的,文件描述符将在范围0 <= fd < max内,但我没有引用资料。 - Dietrich Epp
在编程时,不要做任何假设。这能让你活得更长久。说真的。 - Randy Howard
@RandyHoward:我认为假设是必要的,以保持我们的理智和效率。 - Dietrich Epp
你可以假设当代码出问题时需要修复的代码最初是由某个人编写的,该人进行了许多不必要的假设。;-) - Randy Howard
1
好吧……至少我来到了 Stack Overflow 并在这里发布了我的问题,以便首先对我的假设进行仔细的审查。另外,我尽可能避免假设,但在这种情况下,“不假设”将需要一个更大的数组,导致更多的缓存未命中,性能明显更差。所有这些都是因为我只有 99.9% 的把握,而不是 100%。 “编程时不要假设任何东西。这让你活得更久。” 而采取经过计算的风险是使人成功和生活更幸福的方法? - Will
“不必要的假设”-- OP询问了“合理”的假设,而你的评论是没有根据的。 - Jim Balter
1个回答

3

POSIX标准中已经有一些函数可以做到这一点了。请看FD_SETSIZEselect()FD_SET


我猜这是来自select手册的内容:fd_set是一个固定大小的缓冲区。如果使用负值或等于或大于FD_SETSIZE的fd值执行FD_CLR()或FD_SET(),将导致未定义的行为。此外,POSIX要求fd必须是有效的文件描述符。 - Will
@Will:请注意,这并不保证您永远无法获得超过FD_SETSIZE的文件描述符,但open确保生成的文件描述符是“小整数”,当它们不小的时候其他东西会出问题。如果您愿意,还可以使用dup2将超出范围的fds移动到范围内(显然选择一个未使用的条目)。 - Ben Voigt
1
感谢您的回复,我注意到在 open 的 man 页面中有以下句子:open()函数应返回用于该进程尚未打开的命名文件的文件描述符,该描述符是当前未使用的最低文件描述符。 我逻辑上理解为任何新的文件描述符都将小于任何打开的文件描述符,或者正好比最大的打开的文件描述符大1,这反过来证明没有文件描述符可以比设定的最大值更大(因为要达到fd> max,你必须打开的fd数必须超过最大值)。也许您可以将此添加到您的答案中(或者我可以自己创建一个答案)。 - Will
再说,虽然这适用于open(),但不一定适用于其他函数,比如accept()。嗯,不管怎样,我已经被说服了。 - Will
@Will:socketaccept的返回值也会传递给select,因此它们需要遵循相同的规则。 - Ben Voigt

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