select()
和pselect()
系统调用会修改它们的参数('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()
,尽管那时您最有可能需要此功能。)
这里有一个相关的SO问题-询问“poll() vs select()”,它涉及到与此问题不同的一组问题。
请注意,在MacOS X上 - 并且可能是BSD更一般 - 有一个FD_COPY()
宏或函数,具有有效原型:
extern void FD_COPY(const restrict fd_set *from, restrict fd_set *to);
。
在尚未提供的平台上模拟值得考虑。
FD_COPY
。 - Carl Norumfd_set
在标准 C 下实现,就永远不会使用已分配的内存。 - R.. GitHub STOP HELPING ICE