【问题标题】:c timeval vs timespecc timeval vs timespec
【发布时间】:2015-09-25 07:52:56
【问题描述】:

除了精度的不同,struct timevalstruct 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 都定义为“长字”。

【问题讨论】:

  • 您为要使用的系统调用使用正确的结构——struct timeval 用于gettimeofday()(和select()),struct timespec 用于clock_gettime()。对于内部处理,您可以使用其中一个或两个,这对您来说很方便。两者之间的转换相对无痛;输入和输出需要一点点注意(主要是确保小数部分的前导零在必要时正确打印和扫描)。 BSD 和 Mac OS X 为struct timeval 提供了一些原始的算术和比较工具; struct timespec 没有类似物。
  • 你应该看看Why C has so many different types,它也在询问struct timeval

标签: c linux time


【解决方案1】:

就个人而言,我两个都不用。我更喜欢将时间表示为一个简单的int64_t,因为这会使时间计算变得非常简单,如果必须,转换回struct timevalstruct timespec 也没有问题。即使您想要纳秒级的精度,int64_t 也可以表示近 585 年的跨度。如果你只需要几毫秒,你就有将近 5.85 亿年的跨度。

【讨论】:

    【解决方案2】:

    我认为这实际上只是 API [in] 兼容性问题。像pselect()clock_gettime() 这样的POSIX-y 调用使用struct timespec。各种文件系统调用,如utimes(),以及一些分类的Linux 调用,如gettimeofday()select(),使用struct timeval。从几个手册页大致概括,我怀疑 struct timeval 有 BSD 遗产,而 struct timespec 是 POSIX。

    如果您要进行间隔测量,则没有理由不利用 clock_gettime() 提供的额外精度 - 但请注意,限制测量精度的通常是硬件,而不是头文件。为显示目的除以一百万并不比除以一千更好或更差。另外,Mac OS X does not support clock_gettime()

    但是,如果您要进行大量文件时间操作,则使用在 API 中使用的 struct timeval 可能更有意义,例如 utimes()struct timeval 在 Linux、BSD 和 Mac OS X 上也有一些比较功能,例如timercmp()timersub()(再次参见手册页)。

    我会根据您打算使用的 API 而不是结构本身来做出决定。 (或者如果需要的话,写一个带有转换方法的包装类。)

    【讨论】:

    • 我当前的 Mac OS X (10.12) 版本支持clock_gettime
    • @ioquatix clock_gettime() 已在 10.12 中添加,在该版本之前,您可以使用 mach_time 获得高精度、单调的时钟。
    【解决方案3】:

    两者都是为 POSIX.1-2001 定义的 AFAIK,因此从可移植性的角度来看,使用哪一个并不重要。最简单的答案是:使用任何你想要调用的 API。

    使用struct timeval 可能会获得与平台相关的尺寸优势:

    类型 suseconds_t 应为有符号整数类型 能够存储至少在 [-1, 1000000] 范围内的值。

    struct timespec 中,第二个成员的类型为longint 在 32 位平台上足以满足 suseconds_t 的要求。但是,在 64 位系统上,time_t 通常是 64 位,因此无论如何都会强制结构填充到 16 个字节。所以规模效益是不可能的。

    【讨论】:

    • 是的,两者仍然是 POSIX,但由于 POSIX.1-2008+TC1,一些使用 struct timeval 的函数被标记为过时。 struct timespec 自 C11 以来也是 ISO C 标准的一部分。
    猜你喜欢
    • 2019-12-02
    • 2018-07-19
    • 1970-01-01
    • 2011-05-17
    • 2015-05-09
    • 2017-09-15
    • 2014-01-16
    • 1970-01-01
    • 2015-09-02
    相关资源
    最近更新 更多