有没有在那里上的fd_set使用结构复制任何平台(用于选择()或PSELECT())导致的问题? [英] Are there any platforms where using structure copy on an fd_set (for select() or pselect()) causes problems?

查看:110
本文介绍了有没有在那里上的fd_set使用结构复制任何平台(用于选择()或PSELECT())导致的问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

选择() PSELECT() 系统调用修改其参数(即的fd_set * 参数),所以输入值告诉系统,文件描述符检查和返回值告诉程序员哪些文件描述符目前可用的。

The select() and pselect() system calls modify their arguments (the 'fd_set *' arguments), so the input value tells the system which file descriptors to check and the return values tell the programmer which file descriptors are currently usable.

如果你要多次打电话给他们的同组文件描述符,你需要确保你有描述每个呼叫的新副本。最明显的方式做到这一点是使用结构复制:

If you are going to call them repeatedly for the same set of file descriptors, you need to ensure that you have a fresh copy of the descriptors for each call. The obvious way to do that is to use a structure copy:

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...
    }
 }

编辑,以删除不正确结构FD_SET 引用 - 正如指出的'R ..的)

(Edited to remove incorrect struct fd_set references - as pointed out by 'R..'.)

我的问题:


  • 是否有任何平台的地方不安全做 FD_SET 值的结构复制如图?

  • Are there any platforms where it is not safe to do a structure copy of the fd_set values as shown?

我而言恐怕有隐藏的内存分配或任何意想不到的那样。 (有宏/函数FD_SET(),FD_CLR(),FD_ZERO()和FD_ISSET()从应用掩模的内部。)

I'm concerned lest there be hidden memory allocation or anything unexpected like that. (There are macros/functions FD_SET(), FD_CLR(), FD_ZERO() and FD_ISSET() to mask the internals from the application.)

我可以看到的MacOS X(达尔文)是安全的;其他基于BSD的系统很可能是安全的,因此。您可以通过记录你知道在你的答案安全等系统的帮助。

I can see that MacOS X (Darwin) is safe; other BSD-based systems are likely to be safe, therefore. You can help by documenting other systems that you know are safe in your answers.

(我有关于如何做好 FD_SET 将有超过8192打开的文件描述符工作,未成年人的关注 - 打开文件的默认最大数量只有256,但最大数量是无限。此外,由于结构是1 KB,则复制code不是可怕高效,但随后通过文件描述符的列表运行重新创建在每个周期的输入掩码不一定是有效的任一。也许你不能做选择()当你有许多文件描述符打开,虽然这是当你最有可能需要的功能。)

(I do have minor concerns about how well the fd_set would work with more than 8192 open file descriptors - the default maximum number of open files is only 256, but the maximum number is 'unlimited'. Also, since the structures are 1 KB, the copying code is not dreadfully efficient, but then running through a list of file descriptors to recreate the input mask on each cycle is not necessarily efficient either. Maybe you can't do select() when you have that many file descriptors open, though that is when you are most likely to need the functionality.)

有一个相关的SO问题 - 问<一个href=\"http://stackoverflow.com/questions/970979/what-are-the-differences-between-poll-and-select\">'poll() VS选择()'其中涉及从这个问题上不同的问题。

There's a related SO question - asking about 'poll() vs select()' which addresses a different set of issues from this question.

请注意,在MacOS X的 - 和presumably BSD更普遍的 - 有一个 FD_COPY()宏或功能,具有有效的原型:

Note that on MacOS X - and presumably BSD more generally - there is an FD_COPY() macro or function, with the effective prototype:


  • 的extern无效FD_COPY(常量限制从FD_SET *,限制FD_SET *到);

  • extern void FD_COPY(const restrict fd_set *from, restrict fd_set *to);.

这可能是值得的平台上仿效它已经不可。

推荐答案

由于结构FD_SET 只是一个普通的C结构,应始终被罚款。我个人不喜欢通过 = 运营商在做结构的复制,因为我已经在很多未获得正常的一套编译器内在函数的平台合作。使用的memcpy()明确,而不是让编译器插入函数调用是一个更好的方式去,在我的书。

Since struct fd_set is just a regular C structure, that should always be fine. I personally don't like doing structure copying via the = operator, since I've worked on plenty of platforms that didn't have access to the normal set of compiler intrinsics. Using memcpy() explicitly rather than having the compiler insert a function call is a better way to go, in my book.

从C规范,部分 6.5.16.1简单赋值(编辑在这里为简便起见):

From the C spec, section 6.5.16.1 Simple assignment (edited here for brevity):

以下情况之一应当持有:

One of the following shall hold:

...


      
  • 左操作数与右边的类型兼容的结构或联合类型的合格的或不合格的版本;

  •   

...

简单赋值的(=),右操作数的值被转换为分配前pression的类型和替换存储在由左操作数所指定的对象的值。

In simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand.

如果被存储在一个对象中的值是通过以任何方式的第一个对象的存储,则该重叠须精确和两个对象应具有兼容类型的合格或不合格的版本重叠另一个目的读;否则,行为是不确定的。

If the value being stored in an object is read from another object that overlaps in any way the storage of the first object, then the overlap shall be exact and the two objects shall have qualified or unqualified versions of a compatible type; otherwise, the behavior is undefined.

所以你去,只要结构FD_SET 是一个实际上是一个常规的C 结构,你保证成功。然而,它不依赖,你的编译器发射某种code的去做,或者依赖于任何的memcpy()内在它使用结构分配。如果您的平台不能对编译器的内在库链接出于某种原因,它可能无法正常工作。

So there you go, as long as struct fd_set is a actually a regular C struct, you're guaranteed success. It does depend, however, on your compiler emitting some kind of code to do it, or relying on whatever memcpy() intrinsic it uses for structure assignment. If your platform can't link against the compiler's intrinsic libraries for some reason, it may not work.

您将发挥一些技巧,如果你有更开放的文件描述符比将适合结构FD_SET 。而linux 手册页说:

You will have to play some tricks if you have more open file descriptors than will fit into struct fd_set. The linux man page says:

这是 FD_SET 是一个固定大小的缓冲区。执行 FD_CLR() FD_SET()与值 FD 为负或等于或大于 FD_SETSIZE更大将导致不确定的行为。此外,POSIX要求 FD 是一个有效的文件描述符。

An fd_set is a fixed size buffer. Executing FD_CLR() or FD_SET() with a value of fd that is negative or is equal to or larger than FD_SETSIZE will result in undefined behavior. Moreover, POSIX requires fd to be a valid file descriptor.

如下所述,它可能不是值得的努力来证明你的code是在所有系统上的安全。 FD_COPY()提供了这样一个使用,并且是presumably,始终保证:

As mentioned below, it might not be worth the effort to prove that your code is safe on all systems. FD_COPY() is provided for just such a use, and is, presumably, always guaranteed:

FD_COPY(安培; fdset_orig,&安培; fdset_copy)替换一个已分配的&放大器; fdset_copy 文件描述符设置副本&放大器; fdset_orig

FD_COPY(&fdset_orig, &fdset_copy) replaces an already allocated &fdset_copy file descriptor set with a copy of &fdset_orig.

这篇关于有没有在那里上的fd_set使用结构复制任何平台(用于选择()或PSELECT())导致的问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆