Linux下应使用clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...)获取进程精确CPU时间,精度纳秒级、开销最小;Windows用GetProcessTimes()但受10–15ms时钟粒度限制;/proc/[pid]/stat需正则提取utime/stime并换算jiffies;getrusage结果偏小因统计语义不同。

Linux 下用 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) 获取进程精确 CPU 时间
这是最直接、开销最小的方案,返回的是进程自启动以来在用户态 + 内核态实际消耗的 CPU 时间(非 wall-clock),精度通常达纳秒级。它不依赖 /proc 或外部工具,也不受系统负载干扰。
常见错误是误用 CLOCK_MONOTONIC 或 CLOCK_REALTIME——它们返回的是墙上时间,和 CPU 占用完全无关。
-
CLOCK_PROCESS_CPUTIME_ID是 POSIX 标准定义的,glibc 2.17+ 默认支持,无需额外链接库 - 调用前必须声明
struct timespec ts,不能只传指针而忽略初始化 - 返回值为
-1时需检查errno == EINVAL(内核不支持该 clock ID,极少见)或权限问题(容器中可能被 cgroup 限制)
Windows 上用 GetProcessTimes() 替代方案及精度陷阱
Windows 没有等价于 CLOCK_PROCESS_CPUTIME_ID 的纳秒级接口。GetProcessTimes() 返回的是 100 纳秒单位的 FILETIME,但底层实际分辨率取决于系统时钟节拍(通常 10–15ms),连续两次调用差值可能恒为 0,尤其在轻量短时任务中。
如果你看到 CPU 时间长期为 0 或突变式增长,大概率不是代码写错了,而是 Windows 计时粒度不够。
立即学习“C++免费学习笔记(深入)”;
- 返回的
FILETIME必须用ULARGE_INTEGER转换为 64 位整数再转微秒/毫秒,直接强转易溢出 -
GetProcessTimes(GetCurrentProcess(), ...)只能获取当前进程;跨进程需OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, ...)权限 - 在 WSL2 中调用该函数会失败(不支持),应优先检测运行环境
/proc/[pid]/stat 中的 utime 和 stime 字段怎么读才准
Linux /proc/[pid]/stat 第 14 和 15 字段(从 1 开始计)分别是 utime(用户态 jiffies)和 stime(内核态 jiffies),但直接读取会踩两个坑:字段位置易偏移、jiffies 需换算成真实时间。
不要用空格分割全部字段——第 10 字段(comm)含空格,会导致后续索引错乱;也不要硬编码字段序号。
- 正确做法:用
std::regex匹配^\d+ \([^)]*\) [RSDZTW] [^ ]* [^ ]* [^ ]* [^ ]* [^ ]* [^ ]* [^ ]* ([^ ]+) ([^ ]+)提取最后两个数字 - jiffies 换算公式为:
(utime + stime) * sysconf(_SC_CLK_TCK),其中_SC_CLK_TCK通常是 100,但某些实时内核可能不同 - 该方式适合后台监控采样,不适合高频调用(每次 open/read 有 syscall 开销)
为什么 getrusage(RUSAGE_SELF, ...) 的 ru_utime/ru_stime 常比 clock_gettime 小
这不是 bug,而是语义差异:getrusage 统计的是“当前线程 + 所有已结束子线程”的 CPU 时间,且子进程调用 wait() 后其资源才合并进来;而 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) 是实时累加、包含所有存活线程。
如果你在多线程程序里看到两者差值明显,大概率是有线程刚创建还没执行,或子进程尚未 wait。
-
ru_utime.tv_sec和ru_stime.tv_sec是struct timeval,单位是秒+微秒,别和timespec混用 - 在 fork 后未 exec 的子进程中调用
getrusage,结果仍反映父进程快照,不是独立统计 - 容器环境下
RUSAGE_CHILDREN可能不可靠(cgroup v2 对子进程资源归集逻辑变化)
真正难的不是选哪个 API,而是理解每个值背后的时间语义:是线程级还是进程级?是否含子进程?是否实时更新?是否受 cgroup 限频影响?这些细节一旦错配,监控图表就会持续误导你排查方向。


















