最直接方式是Windows用GetTickCount64(毫秒级,排除挂起时间),Linux/macOS用sysinfo(秒级,uptime字段);二者均无需特殊权限,语义统一且开销小,应避免误用QueryPerformanceCounter或system_clock等无关接口。

Windows 下用 GetTickCount64 获取开机时长(毫秒级)
这是最直接、开销最小的方式,返回自系统启动以来的毫秒数,64 位值避免了 49.7 天溢出问题。它不依赖权限,也不需要高精度计时器支持。
注意:GetTickCount64 返回的是“挂起时间不计入”的真实运行时间(即从上次开机到当前,排除休眠/睡眠期间),符合通常说的“已开机时长”语义。
- 需包含头文件
- 返回值类型为
ULONGLONG,别用int或DWORD接收,否则截断 - 若在 Windows XP 或更早系统上运行(极少见),该函数不存在,需用
GetTickCount+ 溢出检测,但现代项目基本不用考虑
ULONGLONG uptime_ms = GetTickCount64(); double uptime_seconds = uptime_ms / 1000.0;
Linux/macOS 下用 sysinfo 获取系统运行时间(秒级)
sysinfo 系统调用返回的 uptime 字段就是自启动以来的秒数,和 uptime 命令、/proc/uptime 一致,精度为秒,无溢出风险。
它比读取 /proc/uptime 更轻量(一次系统调用 vs 文件 I/O),且跨内核版本稳定。
立即学习“C++免费学习笔记(深入)”;
- 需包含
和 -
sysinfo返回 0 表示成功,-1 表示失败(如内存不足),务必检查返回值 - 结构体字段
uptime是long类型,32 位系统下约可支撑 68 年,足够覆盖绝大多数场景
struct sysinfo info;
if (sysinfo(&info) == 0) {
long uptime_seconds = info.uptime;
}
跨平台封装建议:避免用 clock_gettime(CLOCK_BOOTTIME)
虽然 CLOCK_BOOTTIME 在 Linux 上能获取包含挂起时间的总时长(类似 Windows 的 QueryUnbiasedInterruptTime),但它和用户常说的“已开机时长”语义不符——多数人想看的是“系统活跃运行了多久”,不是“通电后过了多久”。而且 macOS 不支持该时钟,Windows 无对应 API,强行跨平台会引入条件编译和语义混淆。
真正需要跨平台且语义统一的方案,应分两层处理:
- Windows:坚持用
GetTickCount64 - POSIX:优先用
sysinfo;若不可用(如某些嵌入式 libc),再 fallback 到读/proc/uptime(第一列) - 完全回避
std::chrono::system_clock或time(0),它们返回的是纪元时间戳,和开机无关
常见误用:把 GetSystemTimeAsFileTime 当开机时间
这个函数返回的是当前 UTC 时间的 FILETIME,和系统启动毫无关系。有人误以为减去某个“开机时刻”就能算出时长,但系统没提供那个基准点——除非你主动记录启动时间(比如服务启动时写日志),否则无法反推。
另一个典型错误是调用 QueryPerformanceCounter 后除以频率来估算,它反映的是高精度计时器滴答,既不保证单调(可能被校准干扰),也不等价于系统运行时间,还受电源策略影响(例如 TSC 不稳定时内核会切换到 ACPI timer)。
简单说:要开机时长,就只信任操作系统明确提供的 uptime 接口,别自己拼凑。











