linux用clock_boottime最可靠,自2.6.39起支持,返回含休眠的单调启动时间;macos需sysctl kern.boottime;windows用gettickcount64();三者语义不同,无跨平台统一定义。

Linux 上用 clock_gettime(CLOCK_BOOTTIME) 最可靠
Linux 从 2.6.39 开始支持 CLOCK_BOOTTIME,它返回自系统启动(含 suspend 时间)以来的单调时间,不受时钟调整影响,是获取 boot time 的首选。注意不是 CLOCK_MONOTONIC——后者在休眠期间暂停计数,会导致 boot time 偏大。
- 必须检查运行时支持:
clock_gettime返回 -1 且errno == EINVAL表示内核不支持,需降级到读/proc/stat -
clock_gettime返回的是纳秒级struct timespec,要转成秒级时间戳需手动除以 1e9 - glibc 2.12+ 默认启用该功能,但嵌入式或旧发行版(如 CentOS 6)可能需要显式链接
-lrt
macOS 只能靠 sysctl 查 kern.boottime
macOS 没有 CLOCK_BOOTTIME,唯一稳定方式是调用 sysctl 获取 kern.boottime,它返回一个 struct timeval,表示 boot 时刻的绝对时间(UTC),不是相对时间。
- 这个值是系统启动时的
realtime,所以要算“已运行多少秒”,得用当前gettimeofday()减去它 - 注意:如果系统启用了 NTP 或时钟跳变,
kern.boottime不会更新,但减法结果仍是逻辑上正确的 uptime 秒数 - 调用前必须初始化
size参数,否则sysctl失败且不报错;常见坑是传了未初始化的size_t size = 0
Windows 用 GetTickCount64() 而非 GetTickCount()
Windows 下最直接的方式是 GetTickCount64(),它返回自系统启动以来的毫秒数,64 位整数,无 49.7 天回绕问题。千万别用老的 GetTickCount()——32 位返回值在运行约 49.7 天后归零,导致 boot time 计算完全错乱。
-
GetTickCount64()在 Windows Vista+ 全面可用,XP 需用GetTickCount()+ 回绕检测,但 XP 已无实际维护价值,可不兼容 - 该函数返回的是相对时间(毫秒),不是绝对时间戳;若需转换为 Unix timestamp,得结合当前系统时间反推 boot 时刻
- 它不包含休眠时间——Windows 的 uptime 定义就是“开机持续运行时间”,和 Linux 的
CLOCK_BOOTTIME语义不同
跨平台封装要注意时钟源语义差异
Linux 的 CLOCK_BOOTTIME、macOS 的 kern.boottime、Windows 的 GetTickCount64() 三者本质不同:前两者试图反映“系统通电至今”,后者只算“内核运行至今”。这意味着在频繁休眠的设备上,Linux/macOS 返回的 boot time 会比 Windows 长得多。
立即学习“C++免费学习笔记(深入)”;
- 不要假设“boot time”在所有平台都指向同一个物理概念;业务逻辑里若依赖该值做超时判断,需明确接受这种差异
- 统一返回类型建议用
std::chrono::nanoseconds或秒级double,避免平台间整数位宽差异(如 Windows 是毫秒,Linux 是纳秒) - 没有银弹:Windows 无法感知 suspend,Linux/macOS 无法精确到硬件加电瞬间,所有方案都是 OS kernel 提供的近似值
真正难的不是调哪个 API,而是意识到“系统启动时间”本身在不同内核里就没有统一定义。










