在c中调用select后超时是否改变?

问题描述 投票:0回答:5

在我的套接字编程作业中,我进行了如下所示的选择调用:

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

电视的类型为

struct timeval

我阅读了 select 的手册页,上面写着:

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

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

c linux sockets posix-select
5个回答
6
投票

是的,确实如此。为了可移植性,您应该在每次调用

select
之前重新初始化它。


5
投票

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


5
投票

来自 POSIX:

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

没有要求这样做,因此可移植代码在

timeout
返回后不得依赖于
select
结构中的值,并且如果再次需要它们,则必须重置它们。参见:

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


3
投票

另请注意,如果出现错误,当 select() 返回时,timeval 结构的内容未定义。由于您不能保证不会出现错误(EINTR 是最常见的),因此您需要一种机制来跟踪剩余时间(如果您关心的话),因此在返回后使用 timeval 结构的内容是浪费时间大多数情况下,即使没有便携性问题。


1
投票

非常重要的注意事项:select() 会并不总是减少超时值。

一般来说,只要 select() 不立即返回,就会减少超时值。

当调用 select() 时,如果已经有数据在等待,尽管 select 调用需要一点时间来执行,超时并没有减少

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

© www.soinside.com 2019 - 2024. All rights reserved.