clockid\u t(clock\u gettime第一个参数)可移植性
大多数POSIX兼容系统提供获取或设置一个高分辨率计时器的功能:clockid\u t(clock\u gettime第一个参数)可移植性,c,time,posix,portability,time.h,C,Time,Posix,Portability,Time.h,大多数POSIX兼容系统提供获取或设置一个高分辨率计时器的功能: int clock_gettime(clockid_t clock_id, struct timespec *tp); 每个系统的文档通常尽可能列出几个符号名clock\u id值,但从未提及实际的数值。事实证明,不同的系统中,不仅数值不同,而且对于相同的含义,符号名称也不相同。更重要的是,并不是系统实际支持的所有时钟都是在time.h(bits/time.h)中定义的——有些时钟只是在linux/time.h中定义的 也就是
int clock_gettime(clockid_t clock_id, struct timespec *tp);
每个系统的文档通常尽可能列出几个符号名clock\u 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环境中(不是逐字摘录):
在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 ...
在苏诺斯:
#define CLOCK_REALTIME ...
#define CLOCK_HIGHRES ... // Synonymous to CLOCK_MONOTONIC_RAW?
在QNX中:
#define CLOCK_REALTIME ...
#define CLOCK_SOFTTIME ...
#define CLOCK_MONOTONIC ...
等等
这让我想知道如何使用
clock\u gettime()
和第一个参数,而不是clock\u REALTIME
。例如,如果我想使用CLOCK\u MONOTONIC\u rough
或CLOCK\u BOOTTIME
,我怎么知道BSD分别调用了CLOCK\u MONOTONIC\u FAST
和CLOCK\u 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\u TAI
,但没有在time.h中定义它,考虑到相同的数值11可能代表CLOCK\u monotic\u precision
或其他系统中的任何东西,我如何检查和使用它呢?如果我试图编写一个最大可移植的程序,我将仅限于相关标准中定义的符号值。(从你所说的,它听起来像是CLOCK\u REALTIME
——也许只有这个值是标准值。)
如果一些系统实现了我想要使用的有用的扩展,我会这样测试它们
#ifdef CLOCK_MONOTONIC_COARSE
... my code calling clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) ...
#endif
如果真的有系统存在,相同的符号值最终意味着明显不同的东西,我会举手宣布这是一场可移植性噩梦,至少我试图远离这种噩梦
在回答你的其他问题时,(1)不,对符号值进行假设是不明智的,(2)没有好的方法来使用一个确实存在但没有时间定义的时钟
另外,您是否假设仅仅因为数字值1在Linux上用于
CLOCK\u monotional
,而在Cygwin下用于CLOCK\u REALTIME
,这意味着这些时钟可能在某种程度上是相同的?情况可能并非如此。这些数字是任意的,你不应该在意它们;这就是符号常量存在的原因 不,做假设是不安全的。首先,您需要研究目标系统上的每个时钟,以查看哪些时钟与另一个系统上的时钟匹配。然后您可能应该使用条件编译(例如,\ifdef\uuuu linux\uuuu
)为您的应用程序选择正确的时钟。@JoachimPileborg在看到所有这些差异后,我现在担心的是,即使是#ifdef uu linux uuu
方法对于所有具有不同程度定制和私有扩展的基于linux的系统(我指的是真正经过大量修改的系统,而不仅仅是重新命名和重新设计的发行版)来说也不够可移植。如果系统未及时定义它,您如何知道系统是否实际支持CLOCK_TAI
。h?@SteveSummit运行时检查是可能的,因为CLOCK_gettime
返回零(如果时钟受支持且当前可用)(具有有效值),否则返回非零。如果所有系统中的数值都相同,那么定义自己的常量就足够了,以避免依赖于系统提供的包含文件(这些文件往往会失去同步),并避免命名不一致。但不幸的是,数值是模糊的,“符号值最终是否意味着截然不同的东西”是一个单独的问题;我天真地希望行为差异应该最小化。相反,我谈论的是相反的问题——不同的系统对于相同的时钟类型有不同的符号名称。因此,我们不能简单地编写#ifdef CLOCK_monotic_rough
——我们必须知道所有系统中该名称的所有别名,例如CLOCK_monotic_FAST
或其他任何东西。时钟未定义但实际受支持的情况并不罕见——我现在在openSUSE中有它。当我刚开始研究其他系统时,我试图做出假设,发现数值不同。然后我意识到符号名称也不同。不,我完全被这种“标准化”搞糊涂了。
#ifdef CLOCK_MONOTONIC_COARSE
... my code calling clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) ...
#endif