clockid_t(clock_gettime 第一个参数)可移植性

问题描述 投票:0回答:1

大多数 POSIX 兼容系统提供获取或设置高分辨率计时器之一的功能:

int clock_gettime(clockid_t clock_id, struct timespec *tp);

每个系统的文档通常会列出几个符号名称作为可能的

clock_id
值,但从未提及实际的数值。事实证明,不仅不同系统的数值不同,而且相同含义的符号名称也不同。更重要的是,并非系统实际支持的所有时钟都在 time.h (bits/time.h) 中定义 - 有些仅在 linux/time.h 中定义。


也就是说,在Linux系统中我们可能有:

#define CLOCK_REALTIME                  0
#define CLOCK_MONOTONIC                 1
#define CLOCK_PROCESS_CPUTIME_ID        2
#define CLOCK_THREAD_CPUTIME_ID         3
#define CLOCK_MONOTONIC_RAW             4
#define CLOCK_REALTIME_COARSE           5
#define CLOCK_MONOTONIC_COARSE          6
#define CLOCK_BOOTTIME                  7
#define CLOCK_REALTIME_ALARM            8
#define CLOCK_BOOTTIME_ALARM            9
#define CLOCK_SGI_CYCLE                10      // In linux/time.h only.
#define CLOCK_TAI                      11      // In linux/time.h only.

在 Cygwin 环境中(不是逐字摘录):

#define CLOCK_REALTIME                  1       // Means CLOCK_MONOTONIC?
#define CLOCK_MONOTONIC                 4       // Means CLOCK_MONOTONIC_RAW?
#define CLOCK_PROCESS_CPUTIME_ID        2
#define CLOCK_THREAD_CPUTIME_ID         3

在 FreeBSD 中:

#define CLOCK_REALTIME                  0
#define CLOCK_VIRTUAL                   1
#define CLOCK_PROF                      2
#define CLOCK_MONOTONIC                 4
#define CLOCK_UPTIME                    5       // Synonymous to CLOCK_BOOTTIME?
#define CLOCK_UPTIME_PRECISE            7
#define CLOCK_UPTIME_FAST               8
#define CLOCK_REALTIME_PRECISE          9       // Same as CLOCK_REALTIME?
#define CLOCK_REALTIME_FAST            10       // Synonymous to CLOCK_REALTIME_COARSE?
#define CLOCK_MONOTONIC_PRECISE        11       // Same as CLOCK_MONOTONIC?
#define CLOCK_MONOTONIC_FAST           12       // Synonymous to CLOCK_MONOTONIC_COARSE?
#define CLOCK_SECOND                   13
#define CLOCK_THREAD_CPUTIME_ID        14
#define CLOCK_PROCESS_CPUTIME_ID       15

在 AIX 中:

#define CLOCK_REALTIME                ...
#define CLOCK_MONOTONIC               ...
#define CLOCK_PROCESS_CPUTIME_ID      ...
#define CLOCK_THREAD_CPUTIME_ID       ...

在 SunOS 中:

#define CLOCK_REALTIME                ...
#define CLOCK_HIGHRES                 ...       // Synonymous to CLOCK_MONOTONIC_RAW?

在 QNX 中:

#define CLOCK_REALTIME                ...
#define CLOCK_SOFTTIME                ...
#define CLOCK_MONOTONIC               ...

等等。


这让我想知道如何以可移植的方式将

clock_gettime()
与除
CLOCK_REALTIME
之外的第一个参数一起使用。例如,如果我想使用
CLOCK_MONOTONIC_COARSE
CLOCK_BOOTTIME
,我怎么知道 BSD 分别将它们称为
CLOCK_MONOTONIC_FAST
CLOCK_UPTIME

根据前 4 个符号名称的数值做出假设是否明智?如:

#define POSIX_CLOCK_REALTIME            0
#define POSIX_CLOCK_MONOTONIC           1
#define POSIX_CLOCK_PROCESS_CPUTIME_ID  2
#define POSIX_CLOCK_THREAD_CPUTIME_ID   3
#define POSIX_CLOCK_MONOTONIC_RAW       4

#if CLOCK_REALTIME == POSIX_CLOCK_MONOTONIC
    #warning This platform has monotonic realtime clock.
#end if
#if CLOCK_MONOTONIC == POSIX_CLOCK_MONOTONIC_RAW
    #warning This platform has undisciplined monotonic clock.
#end if

如果一个系统实际上支持

CLOCK_TAI
但没有在 time.h 中定义它,考虑到相同的数值 11 可能代表
CLOCK_MONOTONIC_PRECISE
或其他系统中的其他内容,我如何检查和使用它?

c time posix portability time.h
1个回答
0
投票

如果我试图编写一个最大程度可移植的程序,我会将自己限制在相关标准中定义的符号值。 (根据你的说法,听起来像

CLOCK_REALTIME
- 也许只有这个值 - 是标准的。)

如果某些系统实现了我想使用的有用扩展,我会通过说

来测试它们
#ifdef CLOCK_MONOTONIC_COARSE
... my code calling clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) ...
#endif

如果确实存在一些系统,其中相同的符号值最终意味着截然不同的事物,我会举手并宣布这是一场可移植性噩梦,至少是我试图保持的那种远离。

在回答您的其他问题时,(1)不,对符号值做出假设是不明智的,(2)没有好方法使用以某种方式确实存在但未在 time.h 中定义的时钟(尽管这种情况希望非常罕见)。

另外,您是否假设仅仅因为数值 1 用于 Linux 上的

CLOCK_MONOTONIC
而用于 Cygwin 下的
CLOCK_REALTIME
就意味着这些时钟可能在某种程度上是相同的?情况可能并非如此。这些数字是任意的,你不应该关心它们;这就是符号常量存在的原因!

© www.soinside.com 2019 - 2024. All rights reserved.