我需要在代码中处理超时情况,如果系统支持Monotonic Clock,我希望使用clock_gettime(CLOCK_MONOTONIC)
。
#ifdef CLOCK_MONOTONIC
clock_gettime(CLOCK_MONOTONIC, & spec);
#else
clock_gettime(CLOCK_REALTIME, & spec);
#endif
我不确定这是否足够。也就是说,是否可能系统定义的CLOCK_MONOTONIC
并不真正支持单调时钟?或者有什么可靠的方法来检查是否支持单调时钟?
3条答案
按热度按时间vngu2lb81#
根据POSIX的规定,即使定义了常量
CLOCK_MONOTONIC
,您实际上也可能需要运行时测试。处理此问题的官方方法是使用_POSIX_MONOTONIC_CLOCK
“feature-test宏”,但这些宏具有非常复杂的语义:引用http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html,如果未定义符号常量或使用值-1定义符号常量,则编译不支持该选项.如果使用大于零得值定义符号常量,则在执行应用程序时始终支持该选项.如果使用值零定义符号常量,则编译支持该选项,并且在运行时可能支持该选项,也可能不支持该选项.
将这三种区别转换为代码,您将得到如下结果:
但是,如果您总是在定义CLOCK_MONOTONIC本身时执行运行时测试,则会更简单,可读性更强:
在当前支持
CLOCK_MONOTONIC
的操作系统上,这会增加代码的大小,但在我看来,可读性的好处是值得的。对于无条件地使用
CLOCK_MONOTONIC
也有相当强的论据;你更有可能找到一个根本不支持clock_gettime
的操作系统(例如,据我所知,MacOSX仍然没有它),而不是一个有clock_gettime
但没有CLOCK_MONOTONIC
的操作系统。yks3o0rb2#
POSIX只要求存在
CLOCK_REALTIME
,其他时钟是可选的。如果单调时钟可用,宏
_POSIX_MONOTONIC_CLOCK
将在unistd.h
中定义(根据man page的Availability部分)ctehm74n3#
正如@zwol的回答所示,事情真的变得有点复杂和有趣--
参见下面的简单程序(
foo.c
):在Linux(Debian 9,x86_64)上:
在macOS(10.13,高Sierra)上:
在FreeBSD(11.1,x86_64)上:
在macOS上的结果真的让我很惊讶。
sysconf()
返回-1
,但是clock_gettime(CLOCK_MONOTONIC)
成功了!不确定这是否表明macOS不符合POSIX。无论如何,它证明了使用sysconf()
进行运行时检查是不可靠的!最后我想说的是: