Die verbleibende Zeit auf einem select () Aufruf
Frage
Ich verwende select()
auf einem Linux / ARM-Plattform, um zu sehen, ob ein UDP-Socket ein Paket erhalten hat. Ich würde gerne wissen, wie viel Zeit in der Auswahl Anruf wurde noch, wenn es vor dem Timeout zurückgibt (ein Paket erfasst hat).
Etwas entlang der Linien von:
int wait_fd(int fd, int msec)
{
struct timeval tv;
fd_set rws;
tv.tv_sec = msec / 1000ul;
tv.tv_usec = (msec % 1000ul) * 1000ul;
FD_ZERO( & rws);
FD_SET(fd, & rws);
(void)select(fd + 1, & rws, NULL, NULL, & tv);
if (FD_ISSET(fd, &rws)) { /* There is data */
msec = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
return(msec?msec:1);
} else { /* There is no data */
return(0);
}
}
Lösung
Die sicherste Sache ist die zweideutige Definition von select()
und Zeit, es selbst zu ignorieren.
Sie einfach die Zeit erhalten vor und nach der Auswahl und subtrahieren, dass aus dem Intervall Sie wollten.
Andere Tipps
Wenn ich richtig erinnern, die select () Funktion behandelt die Zeitüberschreitung und einen I / O-Parameter und, wenn das Auswahl liefert die Zeit in dem Timeout-Variable zurückgegeben wird, bleibt.
Andernfalls werden Sie die aktuelle Zeit vor dem Aufruf, und wieder nach und erhalten die Differenz zwischen den beiden aufnehmen müssen.
Von "man wählen" auf OSX:
Timeout is not changed by select(), and may be reused on subsequent calls, however it
is good style to re-ini-tialize it before each invocation of select().
Sie werden rufen müssen gettimeofday vor dem Aufruf auswählen und dann gettimeofday auf Ausgang.
[Bearbeiten] Es scheint, dass Linux ist etwas anders:
(ii) The select function may update the timeout parameter to indicate
how much time was left. The pselect function does not change
this parameter.
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.
Linux select () aktualisiert das Timeout-Argument, um die Zeit zu reflektieren, die Vergangenheit hat.
Beachten Sie, dass diese über andere Systeme nicht tragbar ist (daher die Warnung in dem O X Handbuch oben zitiert) aber funktionieren mit Linux.
Gilad
nicht wählen Sie verwenden, versuchen Sie mit fd größer als 1024 mit Ihrem Code und sehen, was Sie erhalten.