从主控集中删除FD时,为什么需要在select调用中更新NFD?

从主控集中删除FD时,为什么需要在select调用中更新NFD?,c,sockets,select,C,Sockets,Select,给定如下所示的select调用: select(fdMax+1, &readFds, NULL, NULL, &timeoutVal) 其中ReadFD会在任何时候更新 增加了新的fd 删除现有fd 每当添加新fd时,我都会更新fdMax。然而,每当删除现有fd时,我想知道是否真的需要更新fdMax 如果我有一个更高的fdMax,但没有足够的FD来读取,这有什么区别?有一个预定义的符号maxfd,您可以使用。然后,无论实际使用的FD数量如何,都不必修改该参数。您可以将fdMax

给定如下所示的select调用:

select(fdMax+1, &readFds, NULL, NULL, &timeoutVal)
其中ReadFD会在任何时候更新

增加了新的fd 删除现有fd 每当添加新fd时,我都会更新fdMax。然而,每当删除现有fd时,我想知道是否真的需要更新fdMax


如果我有一个更高的fdMax,但没有足够的FD来读取,这有什么区别?

有一个预定义的符号maxfd,您可以使用。然后,无论实际使用的FD数量如何,都不必修改该参数。

您可以将fdMax设置为系统支持的最大文件描述符值,该值可以由FD_SETSIZE表示,不必担心,但可能会导致效率低下。select将使用fdMax值作为何时可以停止对文件描述符表的线性扫描的提示。如果您撒谎选择,可能会导致它循环的时间比查找感兴趣的文件描述符实际需要的时间长得多

在Linux中,函数max_select_fd使用fdMax开始向后扫描相关文件描述符


在FreeBSD中,如果fdMax较大,则函数kern_select将fdMax调整为进程的最高打开文件描述符。对于纯服务器,这看起来是一个很好的启发式选择,但对于一个小心地将套接字文件描述符的值保持在比其他文件描述符低的值的系统来说,这可能仍然太大。

FD_SETSIZE是FD_set中位数组的大小。@o11c:谢谢,我已经调整了答案。这有时只是一个常量,它被输入到一些数组声明中,在这样的系统中,可以通过将FD_SETSIZE重新定义为一个更大的值来增加select可以处理的文件描述符的数量。是的,我已经这样做了,可以说您应该始终将rlimmit_NOFILE设置为当前TU的FD_SETSIZE。但是,不管您是否重新定义了它,在任何给定的TU中,它都将匹配fd_集的大小。当然,使用不同定义的不同TU只是自找麻烦,它确实属于CPPFLAGS。值得注意的是,您几乎应该始终使用poll(POSIX)或特定于操作系统的东西,如epoll或kqueue。@o11c:select的内核实现相当有效。依赖select的用户代码通常维护自己的活动文件描述符稀疏数组,并与返回的集进行比较,以避免使用while fd