Как показано в ответе @ zwol, все становится немного сложнее и интереснее -
См. Следующую простую программу (foo.c
):
#include <stdio.h>
#include <unistd.h>
#include <time.h>
int
main()
{
struct timespec spec;
printf("_POSIX_MONOTONIC_CLOCK = %d\n",
(int)_POSIX_MONOTONIC_CLOCK);
printf("sysconf(_SC_MONOTONIC_CLOCK) = %ld\n",
sysconf(_SC_MONOTONIC_CLOCK) );
printf("clock_gettime(CLOCK_MONOTONIC) = %d\n",
clock_gettime(CLOCK_MONOTONIC, & spec) );
return 0;
}
В Linux (Debian 9, x86_64):
[STEP 101] # uname -a
Linux debian9 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1 (2018-04-29) x86_64 GNU/Linux
[STEP 102] # gcc foo.c && ./a.out
_POSIX_MONOTONIC_CLOCK = 0
sysconf(_SC_MONOTONIC_CLOCK) = 200809
clock_gettime(CLOCK_MONOTONIC) = 0
[STEP 103] #
В macOS (10.13, High Sierra):
[STEP 201] $ uname -a
Darwin macbook.home 17.5.0 Darwin Kernel Version 17.5.0: Fri Apr 13 19:32:32 PDT 2018; root:xnu-4570.51.2~1/RELEASE_X86_64 x86_64
[STEP 202] $ cc foo.c && ./a.out
_POSIX_MONOTONIC_CLOCK = -1
sysconf(_SC_MONOTONIC_CLOCK) = -1
clock_gettime(CLOCK_MONOTONIC) = 0
[STEP 203] $
В FreeBSD (11.1, x86_64):
[STEP 301] # uname -a
FreeBSD freebsd 11.1-RELEASE FreeBSD 11.1-RELEASE #0 r321309: Fri Jul 21 02:08:28 UTC 2017 root@releng2.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC amd64
[STEP 302] # cc foo.c && ./a.out
_POSIX_MONOTONIC_CLOCK = 200112
sysconf(_SC_MONOTONIC_CLOCK) = 200112
clock_gettime(CLOCK_MONOTONIC) = 0
[STEP 303] #
Результат на macOS действительно удивил меня. sysconf()
возвращает -1
, но clock_gettime(CLOCK_MONOTONIC)
успешно! Не уверен, что это означает, что macOS не соответствует POSIX. В любом случае это доказывает, что проверка во время выполнения с sysconf()
не надежна!
Наконец-то я пойду с этим:
int
Clock_gettime(struct timespec * spec)
{
static bool firstime = true;
static clockid_t clock = CLOCK_REALTIME;
if (firstime) {
firstime = false;
#ifdef CLOCK_MONOTONIC
if (clock_gettime(CLOCK_MONOTONIC, spec) == 0) {
clock = CLOCK_MONOTONIC;
return 0;
}
#endif
}
return clock_gettime(clock, spec);
}