如何在跨平台的 C++ 中获取系统启动/启动时间(以毫秒为单位)(它应该在 Windows / IOS / Android / MAC 中工作)

问题描述 投票:0回答:1

我用c++编写了一个框架dll,它可以在windows、Mac、Android、IOS等跨平台上使用。我需要实现一个 API get_time_since_boot_milli_seconds() ,它将为我提供自系统跨平台(windows / mac / IOS / Android)启动以来的毫秒时间。

我找到了像 GetTickCount64() 这样的函数,但它只能在 Windows 中使用。同样,有些功能仅适用于 Mac。我尝试过 std::chrono ,但没有得到任何相关的API。

我期望标准的 std C++ 函数可以在每个平台上启动后给我以毫秒为单位的时间。

c++ c++11
1个回答
0
投票

我认为标准计时器都不能提供正常运行时间保证。所以是的,你必须自己做。

Windows

#if (_WIN32_WINNT >= 0x0600)
uint64_t    uptime_milli = GetTickCount64();
#else
uint32_t    uptime_milli = GetTickCount();
#endif

上述解决方案应包括睡眠/挂起和休眠时间。 根据您支持的操作系统版本范围,您可能需要将编译时

#if
替换为运行时测试
GetTickCount64
是否在“kernel32.dll”中可用。

替代解决方案是使用

QueryUnbiasedInterruptTime()
。它不包括睡眠/挂起/休眠时间,但它更可靠(从某种意义上说,用户不能作弊和干扰)。


较新的基于 Posix 的平台自 Linux 2.6.39 起):

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 秒的睡眠时间,然后停止计数。

© www.soinside.com 2019 - 2024. All rights reserved.