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

njthzxwz  于 2023-10-16  发布在  其他
关注(0)|答案(1)|浏览(146)

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

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

每个系统的文档通常列出几个符号名称作为可能的clock_id值,但从未提到实际的数值。事实证明,不同系统中不仅数值不同,符号名称也不相同,含义相同。更重要的是,并非所有系统实际支持的时钟都在 time.hbits/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_COARSECLOCK_BOOTTIME,我怎么知道BSD分别将它们称为CLOCK_MONOTONIC_FASTCLOCK_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或其他系统中的任何东西?

zd287kbt

zd287kbt1#

如果我试图写一个最大可移植的程序,我会把自己限制在相关标准中定义的符号值上。(从你所说的,听起来像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,就意味着这些时钟可能是相同的?可能不是这样的。数字是任意的,你不应该关心它们;这就是为什么符号常量存在!

相关问题