2009-01-27 10 views
5

J'utilise select() sur une plate-forme Linux/ARM pour voir si un socket udp a reçu un paquet. Je voudrais savoir combien de temps il restait dans l'appel select s'il revenait avant le timeout (ayant détecté un paquet).Temps restant sur un appel select()

Quelque chose le long des lignes de: fonction

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); 
    } 
} 
+0

Je ne suis pas sûr de savoir quelle est votre question. Votre code résout le problème; Le temps restant est écrit dans le paramètre timeout. Quoth select (2): "Sous Linux, select() modifie le timeout pour refléter le temps non dormi, la plupart des autres implémentations ne le font pas (POSIX.1-2001 autorise l'un ou l'autre comportement.)" – phihag

+0

@phihag: "permis soit comportement "... regardant exactement la valeur de timeout après un appel select est non-portable –

Répondre

3

La chose la plus sûre est d'ignorer la définition ambiguë de select() et le temps vous-même.

Juste obtenir le temps avant et après le sélectionner et soustraire cela de l'intervalle que vous vouliez.

+0

J'ai fini par faire cela avec un appel de fonction gettimeofday() avant et après. – Jamie

1

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

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

+0

La documentation pour select() indique que la valeur de timeout 'peut' être changée si les fonctions sont retournées avec succès (ne pas timeout). Je me demandais s'il y avait un simple idiome ou un autre appel de bibliothèque pour faire cela. – Jamie

+0

Puisque vous écrivez votre application pour une plate-forme spécifique, pourquoi ne pas simplement l'essayer et voir si la valeur du délai d'attente est modifiée après l'appel sur cette plate-forme. –

+0

J'ai juste eu une relecture du document C, et je suis d'accord, l'utilisation du timeout est au mieux ambiguë. Comme Adam a dit que vous pouvez l'essayer et voir pour votre plate-forme, sinon c'est mon plan de suggestion B pour vous. –

1

De « l'homme sélectionner » sur Mac OS X:

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 sélectionner, puis gettimeofday à la sortie.

[Modifier] Il semble que linux est 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. 
0

Linux select() met à jour l'argument de délai d'attente pour tenir compte du temps qui a passé. Notez que ceci n'est pas portable sur d'autres systèmes (d'où l'avertissement dans le manuel d'OS X cité ci-dessus) mais fonctionne avec Linux.

Gilad

-3

N'utilisez pas select, essayez avec fd plus grand que 1024 avec votre code et voyez ce que vous obtiendrez.

+0

Ok ... c'est un vieux fil de discussion, mais que dois-je utiliser? – Jamie

Questions connexes