在c中选择调用后是否更改了超时?

时间:2010-12-10 08:40:24

标签: c linux sockets select

在我的套接字编程分配中,我做了一个这样的选择调用:

select(s+1, &rfds, (fd_set *)0, (fd_set *)0,&tv)

其中tv的类型为struct timeval

我阅读了select的手册页,它说:

  

在Linux上,函数select修改超时以反映未睡眠的时间;大多数其他实现不会这样做。这会导致读取超时的Linux代码移植到其他操作系统,以及将代码移植到Linux时,在循环中重复使用struct timeval进行多次选择而不重新初始化它时会出现问题。在select返回后,请考虑超时未定义。

这是否意味着我的电视变量会在调用select之后被更改? (我正在使用Ubuntu)

5 个答案:

答案 0 :(得分:6)

是的,确实如此。为了便于携带,您应该在每次调用select之前重新初始化它。

答案 1 :(得分:5)

变量仍将指向相同的结构,但结构的内容将被更改。

答案 2 :(得分:3)

另请注意,出现错误时,select()返回时timeval结构的内容未定义。既然你不能保证不会出错(EINTR是最常见的)你还需要一种机制来跟踪剩余时间(如果你在意),所以在返回后使用timeval结构的内容是浪费时间大多数情况甚至没有可移植性问题。

答案 3 :(得分:2)

来自POSIX:

  

成功完成后,select()函数可能会修改超时参数指向的对象。

没有要求,因此可移植代码在timeout返回后不得依赖select结构中的值,如果再次需要,则必须重置它们。参见:

http://www.opengroup.org/onlinepubs/9699919799/functions/select.html

答案 4 :(得分:1)

非常重要的说明:select()将并不总是减少超时值。

通常只要select()不立即返回,它就会减少超时值。

当调用select()时,如果有数据已经​​等待,尽管选择调用需要花费一点时间来执行,超时不会减少

因此,在繁忙的系统中,将其用作时间测量是危险的。我们添加了一个解决方法,可以检测何时运行select并且timeout的值没有降低,并且在这种情况下会稍微减少它,以便超时仍然会定期达到0。