linux用sysinfo()直接获取uptime秒数,macos需用sysctl读kern.boottime再减当前时间,windows推荐gettickcount64;三者均表示系统启动后运行时长(含休眠),跨平台封装须统一为std::chrono::seconds并预处理器判断。

Linux 下用 sysinfo 读取系统启动时间最直接
Linux 内核通过 sysinfo 系统调用暴露了系统运行时长(uptime),C++ 程序可以直接调用它,无需解析命令行或读文件。它的返回值是秒级整数,精度足够日常使用。
常见错误是误以为要自己算时间戳差值——其实 sysinfo 返回的 uptime 字段就是从开机到现在经过的秒数,不是当前时间戳。
- 包含头文件:
#include <sys></sys> - 声明结构体:
struct sysinfo info;,然后调用sysinfo(&info) - 检查返回值:失败时
sysinfo()返回 -1,errno可能为EPERM(极少见)或EFAULT(指针非法) -
info.uptime是long类型,单位秒;转成可读格式可用std::chrono::seconds(info.uptime)
macOS 不支持 sysinfo,得用 sysctl 查 kern.boottime
macOS 没有 sysinfo,但提供 kern.boottime 这个 sysctl 值,返回的是 boot time 的 struct timeval,即开机时刻的时间戳。你需要用它和当前时间做减法来算 uptime。
容易踩的坑是直接把 kern.boottime 当作秒数用——它给的是绝对时间,不是持续时间。
立即学习“C++免费学习笔记(深入)”;
- 需要两个
int mib[2] = {CTL_KERN, KERN_BOOTTIME}; - 调用
sysctl(mib, 2, &tv, &size, nullptr, 0),其中tv是struct timeval - 再调用
gettimeofday(&now, nullptr),然后计算now.tv_sec - tv.tv_sec - 注意:
tv.tv_usec和now.tv_usec也要参与计算,否则毫秒级误差可能累积
Windows 用 GetTickCount64 足够,别碰 GetSystemTimeAsFileTime
Windows 的 GetTickCount64 返回系统启动后经过的毫秒数,是唯一推荐方式。它线程安全、无权限要求、精度足够(10–16ms),且不会像老版 GetTickCount 那样溢出。
有人试图用 GetSystemTimeAsFileTime 减去注册表里的 LastBootUpTime,这是错的:注册表值不实时更新,且涉及权限和字符串解析,纯属给自己加戏。
- 函数在
<windows.h></windows.h>中声明,返回ULONGLONG - 除以 1000 得到秒数,或用
std::chrono::milliseconds构造 duration - 该值从系统启动开始计,休眠/睡眠期间**继续计时**(符合 uptime 语义)
- 不要用
QueryPerformanceCounter:它测的是高精度间隔,不是 uptime
跨平台封装要注意时钟源语义差异
三个平台的“uptime”定义其实一致:系统最近一次启动后持续运行的时间(含休眠)。但实现机制不同,封装时不能只看数值,得守住这个语义边界。
最容易被忽略的是 Windows 上的 GetTickCount64 和 Linux 的 sysinfo.uptime 都不含 NTP 调整,而 macOS 的 kern.boottime 是 wall-clock 时间戳,理论上受系统时间修改影响——不过实际中,内核会保证 kern.boottime 不随 settimeofday 改变,所以仍是可信的。
- 别在跨平台代码里假设所有系统都支持
sysinfo,预处理器判断必不可少 - 返回值统一用
std::chrono::seconds或uint64_t(秒),避免裸long在不同平台宽度不一致 - 如果程序需容忍虚拟机暂停(如 suspend-to-RAM),目前没有标准 API 能区分“挂起时长”,只能接受 OS 报告的 uptime










