The select() and pselect() http://www.opengroup.org/onlinepubs/9699919799/functions/pselect.html系统调用修改它们的参数('fd_set *
' 参数),因此输入值告诉系统要检查哪些文件描述符,返回值告诉程序员哪些文件描述符当前可用。
如果您要针对同一组文件描述符重复调用它们,则需要确保每次调用都有描述符的最新副本。最明显的方法是使用结构副本:
fd_set ref_set_rd;
fd_set ref_set_wr;
fd_set ref_set_er;
...
...code to set the reference fd_set_xx values...
...
while (!done)
{
fd_set act_set_rd = ref_set_rd;
fd_set act_set_wr = ref_set_wr;
fd_set act_set_er = ref_set_er;
int bits_set = select(max_fd, &act_set_rd, &act_set_wr,
&act_set_er, &timeout);
if (bits_set > 0)
{
...process the output values of act_set_xx...
}
}
(编辑删除不正确的struct fd_set
参考文献 - 正如“R..”所指出的。)
我的问题:
- 是否有任何平台无法安全地进行结构复制
fd_set
值如图所示?
我担心会有隐藏的内存分配或任何意外的事情。 (有宏/函数 FD_SET()、FD_CLR()、FD_ZERO() 和 FD_ISSET() 可以从应用程序中屏蔽内部结构。)
我可以看到 MacOS X (Darwin) 是安全的;因此,其他基于 BSD 的系统可能是安全的。您可以通过在答案中记录您知道安全的其他系统来提供帮助。
(我确实有点担心fd_set
可以处理超过 8192 个打开的文件描述符 - 默认打开文件的最大数量仅为 256,但最大数量是“无限制”的。此外,由于结构为 1 KB,因此复制代码的效率并不高,但随后运行文件描述符列表以在每个周期重新创建输入掩码也不一定高效。也许你做不到select()
当您打开那么多文件描述符时,尽管那是您最有可能需要该功能的时候。)
有一个相关的问题 - 询问'poll() 与 select()' https://stackoverflow.com/questions/970979/what-are-the-differences-between-poll-and-select它解决了与此问题不同的一组问题。
请注意,在 MacOS X 上——大概还有更普遍的 BSD 上——有一个FD_COPY()
宏或函数,具有有效原型:
-
extern void FD_COPY(const restrict fd_set *from, restrict fd_set *to);
.
在尚不可用的平台上可能值得效仿。