c timeval vs timespec

помимо разницы в точности, каковы различия между struct timeval и struct timespec? Если мне нужно меньше точности, чем µs (скажем, миллисекунды), почему я должен использовать один над другим?

на моем компиляторе (gcc для 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.  */
  };

С __syscall_slong_t и __suseconds_t определяется как"длинное слово".

3 ответов


я думаю, что это действительно просто вопрос совместимости API [in]. POSIX-y вызывает как pselect() и clock_gettime() использовать struct timespec. Различные вызовы файловой системы, такие как utimes(), и некоторые сортированные вызовы Linux, такие как gettimeofday() и select() используйте struct timeval. Широко обобщая из нескольких man-страниц, я подозреваю, что struct timeval имеет наследие BSD, тогда как struct timespec это POSIX.

если вы делаете интервал измерения, нет причин не использовать дополнительную точность от clock_gettime() - хотя будьте осторожны, что это обычно аппаратное обеспечение, а не файл заголовка, который ограничивает точность измерения. Деление на миллион для целей отображения вряд ли лучше или хуже, чем деление на тысячу. Кроме того,Mac OS X не поддерживает clock_gettime().

но если вы делаете много манипуляций с временем файла, может иметь смысл использовать struct timeval используется в API, как utimes(). struct timeval также имеет некоторые функции сравнения в Linux, BSD и Mac OS X, например timercmp(), timersub() (опять же, см. man pages).

я бы принял решение на основе API, которые вы собираетесь использовать, а не на самих структурах. (Или написать класс-оболочку с методами преобразования, если это необходимо.)


оба AFAIK определены для POSIX.1-2001, так и с точки зрения переносимости, не имеет значения, какой вы используете. Самый простой ответ: используйте то, что вам нужно для API, который вы собираетесь вызвать.

может быть польза от размера, зависящая от платформы, с помощью struct timeval:

тип suseconds_t должен быть целочисленным типом со знаком способен хранить ценности, по крайней мере в диапазоне [-1, 1000000].

на struct timespec второй член имеет тип long. Ан int было бы достаточно на 32-битной платформе для выполнения suseconds_t требований. Но, на 64-битной системе, time_t обычно 64 бит, таким образом, заставляя структуру заполнять до 16 байт в любом случае. Так что размер пособия ... маловероятен.


лично я не использую ни один. Я предпочитаю выражать время как простой int64_t потому что это делает вычисления времени мертвыми простыми, и если вам нужно, преобразование обратно в struct timeval или struct timespec - это не проблема. Даже если вы хотите точность наносекунд,int64_t может выразить почти 585 лет. Если вам просто нужны миллисекунды, у вас есть промежуток почти 585 миллионов лет.