Temps restant sur un appel select ()
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);
}
}
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.