Question

J'utilise select() sur une plate-forme Linux / ARM pour voir si un socket udp a reçu un paquet. J'aimerais savoir combien de temps il restait dans l'appel sélectionné s'il est renvoyé avant l'expiration du délai (après avoir détecté un paquet).

Quelque chose dans le sens de:

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);
    }
}
Était-ce utile?

La solution

Le plus sûr est d'ignorer la définition ambiguë de select() et de la chronométrer vous-même.

Obtenez simplement le temps avant et après la sélection et soustrayez-le de l'intervalle souhaité.

Autres conseils

Si je me souviens bien, la fonction select () traite le délai d'attente et un paramètre d'E / S et, lorsque select renvoie, le temps restant est renvoyé dans la variable de délai d'attente.

Sinon, vous devrez enregistrer l'heure actuelle avant d'appeler, puis après et obtenir la différence entre les deux.

De " man select " sous 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().

Vous devez appeler gettimeofday avant d'appeler select, puis gettimeofday à la sortie.

[Modifier] Il semble que linux soit légèrement différent:

   (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 () met à jour l'argument de délai d'expiration pour refléter le temps écoulé.

Notez que ce n'est pas portable sur d'autres systèmes (d'où l'avertissement dans le manuel OS X cité ci-dessus) mais fonctionne avec Linux.

Gilad

N'utilisez pas select, essayez avec un code supérieur à 1024 avec votre code et voyez ce que vous obtiendrez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top