Как получить время загрузки / загрузки системы в миллисекундах в C ++ в кросс-платформенном режиме (должно работать в Windows / IOS / Android / MAC) - PullRequest
0 голосов
/ 18 мая 2019

Я написал фреймворк dll на c ++, который используется в кросс-платформенных системах, таких как Windows, Mac, Android, IOS.Мне нужно реализовать один API get_time_since_boot_milli_seconds (), который даст мне время в миллисекундах после загрузки кроссплатформенной системы (windows / mac / IOS / Android).

Я нашел функцию, подобную GetTickCount64 (), но она работаеттолько в окнах.Аналогично есть функция, которая работает только в Mac.Я пробовал std :: chrono, но не получил никакого соответствующего API.

Я ожидаю, что стандартная функция C ++, стандартная стандартизация, может дать мне время в миллисекундах с момента загрузки на каждой платформе.

1 Ответ

0 голосов
/ 20 мая 2019

Я думаю, что ни один из стандартных таймеров не обеспечивает гарантированное время безотказной работы. Так что да, ты сам должен это сделать.

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 секунд сна, а затем останавливает счет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...