在我的套接字编程分配中,我做了一个这样的选择调用:
select(s+1, &rfds, (fd_set *)0, (fd_set *)0,&tv)
其中tv的类型为struct timeval
我阅读了select的手册页,它说:
在Linux上,函数select修改超时以反映未睡眠的时间;大多数其他实现不会这样做。这会导致读取超时的Linux代码移植到其他操作系统,以及将代码移植到Linux时,在循环中重复使用struct timeval进行多次选择而不重新初始化它时会出现问题。在select返回后,请考虑超时未定义。
这是否意味着我的电视变量会在调用select之后被更改? (我正在使用Ubuntu)
答案 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。