web-dev-qa-db-fra.com

c timeval vs timespec

Outre la différence de précision, quelles sont les différences entre struct timeval et struct timespec? Si j'ai besoin de moins de précision que µs (disons, millisecondes), pourquoi devrais-je utiliser l'un sur l'autre?

Sur mon compilateur (gcc pour ARM):

/* POSIX.1b structure for a time value.  This is like a `struct timeval' but
   has nanoseconds instead of microseconds.  */
struct timespec
  {
    __time_t tv_sec;        /* Seconds.  */
    __syscall_slong_t tv_nsec;  /* Nanoseconds.  */
  };

/* A time value that is accurate to the nearest
   microsecond but also has a range of years.  */
struct timeval
  {
    __time_t tv_sec;        /* Seconds.  */
    __suseconds_t tv_usec;  /* Microseconds.  */
  };

Avec __syscall_slong_t et __suseconds_t définis comme un "mot long".

8
Julien-L

Je pense que c'est vraiment juste une question de compatibilité API. Les appels POSIX-y tels que pselect() et clock_gettime() utilisent struct timespec. Divers appels de systèmes de fichiers tels que utimes() , et certains appels Linux variés tels que gettimeofday() et select() , utilisez struct timeval. Généralement, à partir de quelques pages de manuel, je soupçonne que struct timeval possède un héritage BSD, alors que struct timespec correspond à POSIX.

Si vous effectuez des mesures d'intervalle, il n'y a aucune raison de ne pas tirer parti de la précision supplémentaire de clock_gettime() - sachez que c'est généralement du matériel, pas le fichier d'en-tête, qui limite votre précision de mesure. Diviser par un million à des fins d’affichage n’est ni meilleur ni pire que de diviser par mille. De plus, Mac OS X ne prend pas en charge clock_gettime() .

Mais si vous faites beaucoup de manipulations de fichiers, il serait peut-être plus judicieux d'utiliser le struct timeval utilisé dans des API comme utimes(). struct timeval possède également des fonctions de comparaison sous Linux, BSD et Mac OS X, par exemple. timercmp(), timersub() (à nouveau, voir les pages de manuel).

Je prendrais la décision en fonction des API que vous avez l'intention d'utiliser, plutôt que des structures elles-mêmes. (Ou écrivez une classe wrapper avec des méthodes de conversion si nécessaire.)

14
lyngvi

Les deux sont AFAIK défini pour POSIX.1-2001, donc du point de vue de la portabilité, peu importe celui que vous utilisez. La réponse la plus simple est: utilisez celui que vous avez besoin pour l'API que vous souhaitez appeler.

Il pourrait y avoir un avantage de taille dépendant de la plate-forme utilisant struct timeval:

Le type suseconds_t doit être un type entier signé Capable de stocker des valeurs au moins dans la plage [-1, 1000000].

dans struct timespec, le deuxième membre est de type long. Un int suffirait sur une plate-forme 32 bits pour répondre aux exigences de suseconds_t. Cependant, sur un système 64 bits, time_t est généralement de 64 bits, forçant ainsi la structure à 16 octets de toute façon. Donc, un avantage de taille est - improbable.

3
user2371524

Personnellement, je n'utilise ni l'un ni l'autre. Je préfère exprimer le temps sous la forme d'un simple int64_t car cela simplifie énormément les calculs de temps. Si vous devez le faire, la reconversion en struct timeval ou struct timespec ne pose pas non plus de problème. Même si vous voulez une précision de nanosecondes, int64_t peut exprimer une durée de presque 585 ans. Si vous avez juste besoin de quelques millisecondes, vous avez une durée de presque 585 millions d'années.

1
Mecki