Linux通过/proc/self/stat第22字段(clock_t)结合/proc/stat的btime和CLK_TCK计算秒级时间戳;macOS用sysctl获取kinfo_proc.p_starttime(微秒级绝对时间);Windows用GetProcessTimes转FILETIME为Unix时间戳(100纳秒精度)。

Linux 下读取 /proc/self/stat 获取启动时间(相对系统启动秒数)
Linux 内核把进程启动时刻记录在 /proc/[pid]/stat 的第 22 个字段(从 1 开始计数),单位是「系统启动后经过的时钟滴答数(clock_t)」,不是 Unix 时间戳。必须结合 /proc/stat 中的 btime(系统启动 Unix 时间戳)换算。
- 用
std::ifstream读取/proc/self/stat,按空格分割并跳过前 21 个字段,提取第 22 字段(starttime) - 读取
/proc/stat,找以btime开头的行(注意末尾有空格),提取其后的整数值 —— 这就是系统启动的秒级 Unix 时间戳 - 调用
sysconf(_SC_CLK_TCK)获取每秒滴答数(通常是 100),计算:btime + starttime / (double)clk_tck - 结果是 double 类型的秒级时间戳,精度取决于
starttime的分辨率(通常为 1/100 秒),达不到纳秒级,但已优于time()
macOS 下用 sysctl + kinfo_proc 获取启动时间
macOS 没有 /proc,需用 sysctl 查询当前进程的 kinfo_proc 结构体,其中 kp_proc.p_starttime 是 struct timeval,含秒和微秒。
- 填入
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; - 调用
sysctl(mib, 4, &kp, &size, nullptr, 0),成功后kp.kp_proc.p_starttime.tv_sec和.tv_usec可组合成微秒级 Unix 时间戳 - 注意:
kinfo_proc在不同 macOS 版本中字段名可能变化(如旧版用kp_proc.p_starttime,新版推荐kp.kp_proc.p_starttime),编译时加-D_DARWIN_BETTER_REALTIME可提升兼容性 - 该方式精度为微秒,且
p_starttime是绝对 Unix 时间,无需额外换算
Windows 下用 GetProcessTimes 转换为 Unix 时间戳
GetProcessTimes 返回的是 FILETIME(100 纳秒为单位的 64 位整数),需转换为 Unix 时间戳(自 1970-01-01 UTC 起的秒数),中间要减去 Windows 纪元偏移量。
在 Windows 上执行终端命令,或对比 Windows 与 Linux 的 Shell 语法时使用。建议先检测当前 Shell 是 PowerShell 还是 cmd.exe,再给出相应命令……
- 声明
FILETIME ftCreate;,调用GetProcessTimes(GetCurrentProcess(), &ftCreate, ...) - 用
ULARGE_INTEGER将ftCreate转为 64 位整数,减去 Windows 纪元到 Unix 纪元的差值:116444736000000000ULL(单位:100 纳秒) - 除以
10000000得到秒级 Unix 时间戳(double或uint64_t),若需更高精度可保留余数作为纳秒部分 - 注意:
GetProcessTimes在沙箱环境(如某些 UWP 或受限策略下)可能失败,需检查返回值
跨平台封装建议与精度陷阱
没有单一 API 能在所有平台返回纳秒级绝对时间戳;各系统提供的原始数据单位、基准和精度都不同。强行统一为 std::chrono::time_point<std::chrono::system_clock> 容易丢失精度或引入偏移。
立即学习“C++免费学习笔记(深入)”;
- 避免用
std::chrono::system_clock::now()减去运行时长估算启动时间 —— 进程可能被挂起,system_clock不保证单调,且无法回溯 - Linux 的
starttime是相对于系统启动的值,若系统 uptime 超过 497 天(clock_t溢出),该字段会回绕,但现代内核已用 64 位字段规避 - macOS 的
p_starttime是 wall-clock 时间,但若系统启用了 NTP 调整,它可能略早于真实 Unix 时间(取决于内核如何填充该字段) - Windows 的 FILETIME 是单调递增的,但转换时若用
double存秒+纳秒,53 位 mantissa 在 2^53 ns ≈ 285 年后开始丢精度 —— 对大多数进程够用,但长期运行服务需留意
真正高精度(纳秒级)且跨平台的方案不存在,得按目标平台分别实现,并接受微秒级已是实用上限。

















