2018-06-19-C里面的几个时间函数(翻译)

翻译一下 几个时间函数 第一个回答,写得比较好。建议看原文,里面有链接的。

问题就在于在 C/C++ 中有多个时间函数,它们在行为和实现方面都有不同。 关于这个问题,网上还有很多“半答案”。把这些函数一起编译一下就可以准确 回答这个问题了。开始前,我想问下我们需要考虑哪些特性呢?看到前面你的描 述,我认为以下几点:

  1. 处理的时哪个时间呢?(实际时间,用户时间,系统时间还是,最好不要, 墙上时钟?)。
  2. 时钟的精度是多少?(秒,毫秒,微秒还是更快?)
  3. 时钟多长时间会绕回来?或者有对应的机制来避免这种情况发生?
  4. 时钟是单调的吗?或者说他会不会随着系统时间的改变而改变?(通过NTP, 时区,夏令时,用户自己设置等竺)。
  5. 上述这些的实现之间的区别?
  6. 对应的函数是否已经废弃?非标准?等等。

开始前呢,我想指出的是,“墙上时钟”一般很少使用。因为它会随着时区的改 变,夏令时的改变或者是NTP改变了系统时间而改变。在需要使用时间来设置事 件或是进行性能测试时,时间的改变可不是什么好事情。它只能说是像它的名字 一样:一个挂在墙上的时钟(或者桌面上)。

下面是我所能找到的Linux和OS X上的“时钟”:

  1. time() 返回系统的墙上时钟,精确到秒。
  2. 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, …)实现的。
  3. clock_gettime(CLOCK_MONOTONIC, ...) 提供了纳秒级的精度,并且它 是单调的。我认为结构体中的“秒”和“纳秒”是分开的,每一个都是单 独的32位数。因此,任何的加绕都只会发生在启动后的很多年之后。 这 看起来是一个很不错的时间,但不幸地是,它现在在OS X中还不支持。 POSIX 7中把 CLOCK_MONOTONIC 描述为一个可选的扩展。
  4. getrusage() 是最适合我使用的函数。它分别返回用户时间和系统时间, 并且不会加绕。在我的系统上面,它的精度是1微秒,但我也在Linux系统 上测试了(Red Hat 4.1.2-48 with GCC 4.1.2),它在Linux上的精度只有1 毫秒。
  5. gettimeofday() 以微秒的精度(字面上)返回墙上时钟。在我的系统上 这个函数是真的有微秒的精度,但这是不能保证的。因为“系统时钟的精 度是依赖于硬件的。POSIX.1-2008上面说:“应该使用 closck_gettime函 数来替换废弃的gettimeofday函数。”所以最好是不用它了。x86的Linux 上把它实现成了一个系统调用。
  6. mach_absolute_time() 是一个OS X上高精度(纳秒级)时钟函数。在我 的系统上,它确实提供了纳秒级的精度。理论上这个接口是会回绕的,但 是他把纳秒保存在一个64位的无符号整型中,所以现实中回绕基本不再是 问题。该函数是否可移植不太确定。

除了特殊说明,上面所有的函数在Linux和OS X中都存在。我的系统是 Apple running OS X 10.8.3 with GCC 4.7.2 from MacPorts

Author: Peng Xie

Created: 2018-10-01 Mon 21:36