gettimeofday() - 为什么同时使用秒和微秒?
gettimeofday() - Why use both seconds and microseconds?
我需要将函数 gettimeofday 用于家庭作业,在阅读手册页和一些在线示例后,我不明白为什么人们有时会同时使用结构的 tv_sec 成员和tv_usec 结构成员。
手册页指出:
The tv argument is a struct timeval (as specified in <sys/time.h>):
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
因此,假设我需要 return 以纳秒为单位的时间,并且我创建了两个时间间隔结构,开始和结束,并且我使用 gettimeofday() 记录了它们的时间。
当然,我的第一个想法是计算微秒的差异,即 start.tv_usec-end.tv_usec 然后乘以 1000 将其转换为纳秒。
但是网上很多例子和教程都是计算秒和微秒的差值,然后换算然后相加。 (e.g.)
我通读了整个手册页,但找不到原因,如果有任何解释,我将不胜感激。
"microseconds" 字段没有足够的 space 来存储过去的所有时间。 "seconds" 字段不够精确。它们一起提供的信息最多。
时间由秒数加上 0 - 999999 范围内的微秒数表示。
tv_sec
保存自 Unix 纪元 — 1970-01-01 00:00:00 +00:00 — 和 tv_usec
(或 tv_nsec
在使用更现代的 struct timespec
) 时保留小数部分 — struct timeval
的值为 [0..999,999] 微秒,struct timespec
.[=43 的值为 [0..999,999,999] 纳秒=]
在 64 位整数普及之前,time_t
是 32 位有符号类型,而 'runs out' 在 2038 年 1 月——自从时代。在单个整数中没有存储亚秒单位的空间。
-2147483647 = 1901-12-13 20:45:53 +00:00
+2147483647 = 2038-01-19 03:14:07 +00:00
即使现在,如果处理纳秒,您也需要 30 位来表示最多 999,999,999 纳秒(以及 20 位来表示最多 999,999 微秒)。纳秒的要求意味着尝试缩放 64 位数字来表示秒和纳秒是不明智的——Y2K38 问题将被推迟大约 280 年,而两部分解决方案将它推迟到宇宙结束之后,这对每个人来说应该足够长了。 (我计划在 5000-01-02 开始处理 Y10K 问题,如果我还在的话。)
因此,虽然不理想,但两部分结构使得使用带有 time_t
值的常规格式化函数变得容易 — 它们有很多,而那些带有 struct tm
来自 time_t
值。而且它们的算术并不难。
我注意到,在某些方面,struct timeval
和 struct timespec
都未被 POSIX 指定。如果 tv_sec
分量为负,struct timeval
或 struct timespec
的 tv_usec
或 tv_nsec
部分的符号是什么(参见 Seconds Since the Epoch — 如果年份<1970或值为负数,则关系未定义)。 POSIX 未定义 tv_sec
的负值行为,这可能是明智的,但确实让生活有点困难。当然,还有"when did which part of which country switch between the Julian and Gregorian calendars?"和"was there a year zero?"的问题也是需要处理的。当 time_t
是一个 32 位数字时,它可以追溯到 1901 年 12 月,这在很大程度上避免了这些问题(但俄罗斯直到十月革命之后才从 Julian 转换为 Gregorian,十月革命发生在 11 月公历)。现在 time_t
通常是一个 64 位数字,BC(或 BCE)年也可以表示。
打印 tv_usec
或 tv_nsec
部分时要小心。请记住通过使用 %.6d
微秒,%.9ld
纳秒来添加足够的前导零,其中必要的转换说明符(d
vs ld
vs …)用于 tv_usec
is not clearly defined in POSIX — but d
is usually correct. (The tv_nsec
会员是long
;这既简单又可靠。)
我需要将函数 gettimeofday 用于家庭作业,在阅读手册页和一些在线示例后,我不明白为什么人们有时会同时使用结构的 tv_sec 成员和tv_usec 结构成员。 手册页指出:
The tv argument is a struct timeval (as specified in <sys/time.h>):
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
因此,假设我需要 return 以纳秒为单位的时间,并且我创建了两个时间间隔结构,开始和结束,并且我使用 gettimeofday() 记录了它们的时间。 当然,我的第一个想法是计算微秒的差异,即 start.tv_usec-end.tv_usec 然后乘以 1000 将其转换为纳秒。
但是网上很多例子和教程都是计算秒和微秒的差值,然后换算然后相加。 (e.g.)
我通读了整个手册页,但找不到原因,如果有任何解释,我将不胜感激。
"microseconds" 字段没有足够的 space 来存储过去的所有时间。 "seconds" 字段不够精确。它们一起提供的信息最多。
时间由秒数加上 0 - 999999 范围内的微秒数表示。
tv_sec
保存自 Unix 纪元 — 1970-01-01 00:00:00 +00:00 — 和 tv_usec
(或 tv_nsec
在使用更现代的 struct timespec
) 时保留小数部分 — struct timeval
的值为 [0..999,999] 微秒,struct timespec
.[=43 的值为 [0..999,999,999] 纳秒=]
在 64 位整数普及之前,time_t
是 32 位有符号类型,而 'runs out' 在 2038 年 1 月——自从时代。在单个整数中没有存储亚秒单位的空间。
-2147483647 = 1901-12-13 20:45:53 +00:00
+2147483647 = 2038-01-19 03:14:07 +00:00
即使现在,如果处理纳秒,您也需要 30 位来表示最多 999,999,999 纳秒(以及 20 位来表示最多 999,999 微秒)。纳秒的要求意味着尝试缩放 64 位数字来表示秒和纳秒是不明智的——Y2K38 问题将被推迟大约 280 年,而两部分解决方案将它推迟到宇宙结束之后,这对每个人来说应该足够长了。 (我计划在 5000-01-02 开始处理 Y10K 问题,如果我还在的话。)
因此,虽然不理想,但两部分结构使得使用带有 time_t
值的常规格式化函数变得容易 — 它们有很多,而那些带有 struct tm
来自 time_t
值。而且它们的算术并不难。
我注意到,在某些方面,struct timeval
和 struct timespec
都未被 POSIX 指定。如果 tv_sec
分量为负,struct timeval
或 struct timespec
的 tv_usec
或 tv_nsec
部分的符号是什么(参见 Seconds Since the Epoch — 如果年份<1970或值为负数,则关系未定义)。 POSIX 未定义 tv_sec
的负值行为,这可能是明智的,但确实让生活有点困难。当然,还有"when did which part of which country switch between the Julian and Gregorian calendars?"和"was there a year zero?"的问题也是需要处理的。当 time_t
是一个 32 位数字时,它可以追溯到 1901 年 12 月,这在很大程度上避免了这些问题(但俄罗斯直到十月革命之后才从 Julian 转换为 Gregorian,十月革命发生在 11 月公历)。现在 time_t
通常是一个 64 位数字,BC(或 BCE)年也可以表示。
打印 tv_usec
或 tv_nsec
部分时要小心。请记住通过使用 %.6d
微秒,%.9ld
纳秒来添加足够的前导零,其中必要的转换说明符(d
vs ld
vs …)用于 tv_usec
is not clearly defined in POSIX — but d
is usually correct. (The tv_nsec
会员是long
;这既简单又可靠。)