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);
    }
}
War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top