2018-06-19-C里面的几个时间函数(翻译)
翻译一下 几个时间函数 第一个回答,写得比较好。建议看原文,里面有链接的。
问题就在于在 C/C++
中有多个时间函数,它们在行为和实现方面都有不同。
关于这个问题,网上还有很多“半答案”。把这些函数一起编译一下就可以准确
回答这个问题了。开始前,我想问下我们需要考虑哪些特性呢?看到前面你的描
述,我认为以下几点:
- 处理的时哪个时间呢?(实际时间,用户时间,系统时间还是,最好不要, 墙上时钟?)。
- 时钟的精度是多少?(秒,毫秒,微秒还是更快?)
- 时钟多长时间会绕回来?或者有对应的机制来避免这种情况发生?
- 时钟是单调的吗?或者说他会不会随着系统时间的改变而改变?(通过NTP, 时区,夏令时,用户自己设置等竺)。
- 上述这些的实现之间的区别?
- 对应的函数是否已经废弃?非标准?等等。
开始前呢,我想指出的是,“墙上时钟”一般很少使用。因为它会随着时区的改 变,夏令时的改变或者是NTP改变了系统时间而改变。在需要使用时间来设置事 件或是进行性能测试时,时间的改变可不是什么好事情。它只能说是像它的名字 一样:一个挂在墙上的时钟(或者桌面上)。
下面是我所能找到的Linux和OS X上的“时钟”:
time()
返回系统的墙上时钟,精确到秒。clock()
看起来会返回用户时间和系统时间的和。它存在于C89及以后的 标准。 有一段时间这应该是循环中的CPU时间,但是现代的标准像POSIX要 求CLOCKS_PER_SEC为1000000。这样的话,它最大能精确到1微秒。在我的 系统时,它确实可以精确到1微秒。 该时钟一旦到达最大值就会回绕(通 常发生在2^32个ticks之后,这对于1MHz的时钟来说并不长。)。clock的 manual上说明了在glibc 2.18之后,它在Linux中是由 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, …)实现的。clock_gettime(CLOCK_MONOTONIC, ...)
提供了纳秒级的精度,并且它 是单调的。我认为结构体中的“秒”和“纳秒”是分开的,每一个都是单 独的32位数。因此,任何的加绕都只会发生在启动后的很多年之后。 这 看起来是一个很不错的时间,但不幸地是,它现在在OS X中还不支持。 POSIX 7中把 CLOCK_MONOTONIC 描述为一个可选的扩展。getrusage()
是最适合我使用的函数。它分别返回用户时间和系统时间, 并且不会加绕。在我的系统上面,它的精度是1微秒,但我也在Linux系统 上测试了(Red Hat 4.1.2-48 with GCC 4.1.2),它在Linux上的精度只有1 毫秒。gettimeofday()
以微秒的精度(字面上)返回墙上时钟。在我的系统上 这个函数是真的有微秒的精度,但这是不能保证的。因为“系统时钟的精 度是依赖于硬件的。POSIX.1-2008上面说:“应该使用 closck_gettime函 数来替换废弃的gettimeofday函数。”所以最好是不用它了。x86的Linux 上把它实现成了一个系统调用。mach_absolute_time()
是一个OS X上高精度(纳秒级)时钟函数。在我 的系统上,它确实提供了纳秒级的精度。理论上这个接口是会回绕的,但 是他把纳秒保存在一个64位的无符号整型中,所以现实中回绕基本不再是 问题。该函数是否可移植不太确定。
除了特殊说明,上面所有的函数在Linux和OS X中都存在。我的系统是 Apple
running OS X 10.8.3 with GCC 4.7.2 from MacPorts
。