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

Ant*_*nov 5 c time portability posix time.h

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

\n\n
int clock_gettime(clockid_t clock_id, struct timespec *tp);\n
Run Code Online (Sandbox Code Playgroud)\n\n

每个系统的文档通常列出几个符号名称作为可能的clock_id值,但从未提及实际的数值。事实证明,不仅不同系统的数值不同,而且相同含义的符号名称也不同。更重要的是,并非系统实际支持的所有时钟都在time.h ( bits/time.h ) \xc2\xad\xe2\x80\x94 中定义,有些仅在linux/time.h中定义。

\n\n
\n\n

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

\n\n
#define CLOCK_REALTIME                  0\n#define CLOCK_MONOTONIC                 1\n#define CLOCK_PROCESS_CPUTIME_ID        2\n#define CLOCK_THREAD_CPUTIME_ID         3\n#define CLOCK_MONOTONIC_RAW             4\n#define CLOCK_REALTIME_COARSE           5\n#define CLOCK_MONOTONIC_COARSE          6\n#define CLOCK_BOOTTIME                  7\n#define CLOCK_REALTIME_ALARM            8\n#define CLOCK_BOOTTIME_ALARM            9\n#define CLOCK_SGI_CYCLE                10      // In linux/time.h only.\n#define CLOCK_TAI                      11      // In linux/time.h only.\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
#define CLOCK_REALTIME                  1       // Means CLOCK_MONOTONIC?\n#define CLOCK_MONOTONIC                 4       // Means CLOCK_MONOTONIC_RAW?\n#define CLOCK_PROCESS_CPUTIME_ID        2\n#define CLOCK_THREAD_CPUTIME_ID         3\n
Run Code Online (Sandbox Code Playgroud)\n\n

在 FreeBSD 中:

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

在 AIX 中:

\n\n
#define CLOCK_REALTIME                ...\n#define CLOCK_MONOTONIC               ...\n#define CLOCK_PROCESS_CPUTIME_ID      ...\n#define CLOCK_THREAD_CPUTIME_ID       ...\n
Run Code Online (Sandbox Code Playgroud)\n\n

在Sun操作系统中:

\n\n
#define CLOCK_REALTIME                ...\n#define CLOCK_HIGHRES                 ...       // Synonymous to CLOCK_MONOTONIC_RAW?\n
Run Code Online (Sandbox Code Playgroud)\n\n

在 QNX 中:

\n\n
#define CLOCK_REALTIME                ...\n#define CLOCK_SOFTTIME                ...\n#define CLOCK_MONOTONIC               ...\n
Run Code Online (Sandbox Code Playgroud)\n\n

等等。

\n\n
\n\n

这让我想知道如何使用clock_gettime()第一个参数而不是以CLOCK_REALTIME可移植的方式使用。例如,如果我想使用CLOCK_MONOTONIC_COARSEor CLOCK_BOOTTIME,我如何知道 BSD分别调用它们CLOCK_MONOTONIC_FAST和?CLOCK_UPTIME

\n\n

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

\n\n
#define POSIX_CLOCK_REALTIME            0\n#define POSIX_CLOCK_MONOTONIC           1\n#define POSIX_CLOCK_PROCESS_CPUTIME_ID  2\n#define POSIX_CLOCK_THREAD_CPUTIME_ID   3\n#define POSIX_CLOCK_MONOTONIC_RAW       4\n\n#if CLOCK_REALTIME == POSIX_CLOCK_MONOTONIC\n    #warning This platform has monotonic realtime clock.\n#end if\n#if CLOCK_MONOTONIC == POSIX_CLOCK_MONOTONIC_RAW\n    #warning This platform has undisciplined monotonic clock.\n#end if\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n

Ste*_*mit 0

如果我试图编写一个最大程度可移植的程序,我会将自己限制在相关标准中定义的符号值。(从你的说法来看,这听起来像是CLOCK_REALTIME——也许只有这个值——是标准的。)

如果某些系统实现了我想要使用的有用扩展,我会通过说来测试它们

#ifdef CLOCK_MONOTONIC_COARSE
... my code calling clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) ...
#endif
Run Code Online (Sandbox Code Playgroud)

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

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

另外,您是否假设仅仅因为数值 1CLOCK_MONOTONIC在 Linux 上使用而CLOCK_REALTIME在 Cygwin 下使用,就意味着这些时钟可能在某种程度上是相同的?情况可能并非如此。这些数字是任意的,你不应该关心它们;这就是符号常数存在的原因!