gettickcount64(windows)、/proc/uptime(linux)、sysctl kern_boottime(macos)分别获取系统启动时长,三者均返回自内核启动以来的运行时间,非当前会话时间,跨平台封装需统一为double秒数并注意精度与错误处理。

Windows 下用 GetTickCount64 获取系统启动时长(毫秒级)
Windows 提供了现成的 API,GetTickCount64 返回自系统启动以来的毫秒数,64 位无符号整型,不会像 GetTickCount 那样 49.7 天溢出。它不依赖用户登录态,只要系统没重启就持续累加。
使用前需包含头文件:#include <windows.h></windows.h>;链接时无需额外库(kernel32.lib 默认链接)。
- 返回值是
ULONGLONG,直接除以 1000 得秒数,再除以 60 得分钟,依此类推 - 若程序权限受限(如沙盒环境),仍可调用,该函数无权限检查
- 注意:它统计的是“系统运行时间”,不是“当前会话运行时间”——即使用户注销重登,数值也不重置
- 示例:
ULONGLONG uptime_ms = GetTickCount64();
→ 比如返回1234567890表示约 14 天 6 小时
Linux 下读取 /proc/uptime 文件获取系统启动时长
Linux 内核通过 /proc/uptime 暴露两个空格分隔的浮点数:第一个是系统正常运行时间(单位秒),第二个是系统空闲时间(通常忽略)。这是最轻量、最通用的方式,无需 root 权限,所有标准发行版都支持。
- 打开并读取该文件即可,用
std::ifstream或fopen都行 - 第一字段为总 uptime 秒数,精度到百分之一秒(例如
1234567.89) - 注意:该值从内核启动开始计,包括所有 CPU idle 时间,但不包含 suspend 时间(休眠期间计时暂停)
- 示例(C++11+):
std::ifstream f("/proc/uptime");<br>double uptime_sec;<br>f >> uptime_sec;
macOS 下用 sysctl 调用 KERN_BOOTTIME 计算 uptime
macOS 没有 /proc,也不能用 Windows API,得靠 sysctl 查询系统启动时间戳,再与当前时间差值计算 uptime。核心是 KERN_BOOTTIME,它返回一个 struct timeval,表示系统启动的绝对时间。
- 需包含:
#include <sys></sys>和<sys></sys> - 调用
sysctl时传入{CTL_KERN, KERN_BOOTTIME},结果存入struct timeval - 再用
gettimeofday(&now, nullptr)获取当前时间,两者相减即为 uptime 秒数(注意处理微秒进位) - 容易漏掉:
sysctl可能失败(比如被 SIP 限制),务必检查返回值是否为 0 - 示例关键片段:
struct timeval boot;<br>size_t len = sizeof(boot);<br>if (sysctl(mib, 2, &boot, &len, nullptr, 0) == 0) {<br> gettimeofday(&now, nullptr);<br> double uptime = difftime(now.tv_sec, boot.tv_sec);<br>}
跨平台封装要注意的兼容性陷阱
写一个统一接口时,别直接拼接 #ifdef,重点在三件事:编译期检测、类型一致性、精度取舍。
- 用
__linux__、_WIN32、__APPLE__宏做条件编译,避免误判(比如 macOS 也定义了__unix__,但不适用 Linux 路径) - 统一返回
double秒数(而非整型),否则 Linux 的小数部分和 Windows 的毫秒截断会丢失精度 - Windows 的
GetTickCount64是单调递增但非 wall-clock 精确;Linux/proc/uptime同样不校准 NTP 调整;macOS 的KERN_BOOTTIME会受系统时间调整影响——三者都不是“绝对精确”,只是工程可用 - 如果程序需要高精度或纳秒级,别指望这个 uptime 值;它只适合监控、日志打标、资源老化判断这类场景
真正麻烦的是 macOS 上 sysctl 的 error handling 和 timeval 运算,一不留神就得到负数或零——这通常意味着调用失败,而不是系统刚启动。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











