In my socket programing assignment, I made a select call like this:
select(s+1, &rfds, (fd_set *)0, (fd_set *)0,&tv)
where tv is of type struct timeval
I read the manual page for select and it said:
On Linux, the function select modifies timeout to reflect the amount of time not slept; most other implementations do not do this. This causes problems both when Linux code which reads timeout is ported to other operating systems, and when code is ported to Linux that reuses a struct timeval for multiple selects in a loop without reinitializing it. Consider timeout to be undefined after select returns.
Does it mean my tv variable will be changed after the call to sel开发者_开发知识库ect? (I'm using Ubuntu)
Yes, it does. For portability, you should re-initialize it before each call to select
.
The variable will still point to the same struct, but the contents of the struct will have been changed.
From POSIX:
Upon successful completion, the select() function may modify the object pointed to by the timeout argument.
There is no requirement that it does, so portable code must not rely on the values in the timeout
struct after select
returns, and must reset them if they're needed again. See:
http://www.opengroup.org/onlinepubs/9699919799/functions/select.html
Also note that on error the contents of the timeval struct are undefined when select() returns. Since you can't guarantee not to get an error (EINTR is most common) you'll need a mechanism to track time remaining (if you care) anyway, so using the contents of the timeval struct after return is a waste of time in most situations even without portability concerns.
Very important note: select() will not always reduce the value of timeout.
In general as long as select() doesn't return immediately, it will decrease the value of the timeout.
When select() is called, if there's data already waiting, despite the select call taking a little bit of time to execute, timeout is not reduced.
Therefore on a busy system it is dangerous to use this as a measurement of time. We added a workaround that would detect when select was run and the value of timeout was not decreased and would decrease it slightly by hand in that case so that timeout would still periodically hit 0.
精彩评论