Я думаю, что ни один из стандартных таймеров не обеспечивает гарантированное время безотказной работы. Так что да, ты сам должен это сделать.
Windows
#if (_WIN32_WINNT >= 0x0600)
uint64_t uptime_milli = GetTickCount64();
#else
uint32_t uptime_milli = GetTickCount();
#endif
Решение, приведенное выше, должно включать время сна / приостановки и спящий режим.
В зависимости от диапазона поддерживаемых версий ОС вы можете заменить время компиляции #if
на время выполнения теста, если GetTickCount64
доступен в "kernel32.dll".
Альтернативное решение - использовать QueryUnbiasedInterruptTime()
. Оно НЕ включает время сна / приостановки / спящего режима, но оно более надежно (в том смысле, что пользователь не может обманывать и вмешиваться).
Более новые платформы на базе Posix:
struct timespec up;
int err = clock_gettime(CLOCK_BOOTTIME, &up);
if (err != 0)
HandleError();
uint64_t uptime_nano = up.tv_sec * 1000000000 + up.tv_nsec;
Интервал, возвращаемый этой функцией, должен включать время ожидания и сна.
Старый Linux (в glibc 2.3.6, не могу проверить, чтобы убедиться):
struct timespec up;
int err = clock_gettime(CLOCK_MONOTONIC, &up);
if (err != 0)
HandleError();
uint64_t uptime_nano = up.tv_sec * 1000000000 + up.tv_nsec;
Время, возвращаемое этим методом, НЕ включает состояния сна / приостановки.
OS X, более ранние версии FreeBSD, Linux и Android :
struct timeval boot;
int mib[] = { CTL_KERN, KERN_BOOTTIME };
size_t size = sizeof(boot);
int err = sysctl(mib, 2, &boot, &size, 0, 0);
if (err != 0)
HandleError();
struct timeval now;
err = gettimeofday(&now, 0);
if (err != 0)
HandleError();
uint64_t uptime_micro = (now.tv_sec * 1000000 + now.tv_usec) - (boot.tv_sec * 1000000 + boot.tv_usec);
Этот метод подвержен гонкам, если для расчета требуется два вызова.
Mac также предлагает функцию mach_absolute_time()
, но его поведение может быть неожиданным: он считает первые 30 секунд сна, а затем останавливает счет.