c timeval 与 timespec
c timeval vs timespec
除了精度不同,struct timeval
和struct timespec
还有什么区别?如果我需要的精度低于 µs(例如,毫秒),为什么我要使用一个而不是另一个?
在我的编译器上(ARM 的 gcc):
/* 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
都定义为 "long word"。
我认为这真的只是 API [in] 兼容性的问题。 POSIX-y调用像pselect()
and clock_gettime()
use struct timespec
. Various filesystem calls like utimes()
, and some assorted Linux calls like gettimeofday()
and select()
,使用struct timeval
。从几个手册页中广泛概括,我怀疑 struct timeval
有 BSD 遗产,而 struct timespec
是 POSIX.
如果您正在进行间隔测量,没有理由不利用 clock_gettime()
的额外精度 — 但请注意,限制测量精度的通常是硬件,而不是头文件。出于显示目的而除以一百万与除以一千相比几乎没有好坏之分。 (另外,Mac OS X prior to 10.12 did not support clock_gettime()
。)
但是如果您要进行大量文件时间操作,使用 API 中使用的 struct timeval
可能更有意义,例如 utimes()
。 struct timeval
在 Linux、BSD 和 Mac OS X 上也有一些比较函数,例如timercmp()
、timersub()
(再次参见手册页)。
我会根据您打算使用的 API 来做出决定,而不是根据结构本身。 (或者如有必要,使用转换方法编写包装器 class。)
两者都是为 POSIX.1-2001 定义的 AFAIK,因此从可移植性的角度来看,使用哪一个都无关紧要。最简单的答案是:使用您想要调用的 API 所需的任何一个。
使用 struct timeval
:
可能会带来依赖于平台的大小优势
The type suseconds_t shall be a signed integer type
capable of storing values at least in the range [-1, 1000000].
在 struct timespec
中,第二个成员的类型为 long
。 int
在 32 位平台上足以满足 suseconds_t
要求。但是,在 64 位系统上,time_t
通常是 64 位,因此无论如何都会强制结构填充到 16 字节。所以尺寸优势是——不太可能。
就我个人而言,我两者都不用。我更喜欢将时间表示为简单的 int64_t
,因为这使得时间计算非常简单,如果必须的话,转换回 struct timeval
或 struct timespec
也没有问题。即使你想要纳秒级的精度,int64_t
也可以表达将近 585 年的跨度。如果只需要几毫秒,那么跨度将近 5.85 亿年。
除了精度不同,struct timeval
和struct timespec
还有什么区别?如果我需要的精度低于 µs(例如,毫秒),为什么我要使用一个而不是另一个?
在我的编译器上(ARM 的 gcc):
/* 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
都定义为 "long word"。
我认为这真的只是 API [in] 兼容性的问题。 POSIX-y调用像pselect()
and clock_gettime()
use struct timespec
. Various filesystem calls like utimes()
, and some assorted Linux calls like gettimeofday()
and select()
,使用struct timeval
。从几个手册页中广泛概括,我怀疑 struct timeval
有 BSD 遗产,而 struct timespec
是 POSIX.
如果您正在进行间隔测量,没有理由不利用 clock_gettime()
的额外精度 — 但请注意,限制测量精度的通常是硬件,而不是头文件。出于显示目的而除以一百万与除以一千相比几乎没有好坏之分。 (另外,Mac OS X prior to 10.12 did not support clock_gettime()
。)
但是如果您要进行大量文件时间操作,使用 API 中使用的 struct timeval
可能更有意义,例如 utimes()
。 struct timeval
在 Linux、BSD 和 Mac OS X 上也有一些比较函数,例如timercmp()
、timersub()
(再次参见手册页)。
我会根据您打算使用的 API 来做出决定,而不是根据结构本身。 (或者如有必要,使用转换方法编写包装器 class。)
两者都是为 POSIX.1-2001 定义的 AFAIK,因此从可移植性的角度来看,使用哪一个都无关紧要。最简单的答案是:使用您想要调用的 API 所需的任何一个。
使用 struct timeval
:
The type suseconds_t shall be a signed integer type capable of storing values at least in the range [-1, 1000000].
在 struct timespec
中,第二个成员的类型为 long
。 int
在 32 位平台上足以满足 suseconds_t
要求。但是,在 64 位系统上,time_t
通常是 64 位,因此无论如何都会强制结构填充到 16 字节。所以尺寸优势是——不太可能。
就我个人而言,我两者都不用。我更喜欢将时间表示为简单的 int64_t
,因为这使得时间计算非常简单,如果必须的话,转换回 struct timeval
或 struct timespec
也没有问题。即使你想要纳秒级的精度,int64_t
也可以表达将近 585 年的跨度。如果只需要几毫秒,那么跨度将近 5.85 亿年。