linux下用clock_gettime(clock_process_cputime_id, &ts)获取的是进程自启动以来用户态与内核态总cpu时间(纳秒级,不含休眠),windows需用getprocesstimes分别读取并转换filetime。

Linux 下用 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) 获取进程 CPU 时间
这个函数返回的是当前进程自启动以来占用的 CPU 时间(不包括休眠时间),精度通常达纳秒级,是 POSIX 标准推荐方式。注意它测的是“CPU 执行时间”,不是墙上时钟流逝时间。
常见错误是传错时钟 ID:CLOCK_MONOTONIC 或 CLOCK_REALTIME 返回的是系统运行时间或挂钟时间,和进程无关;必须用 CLOCK_PROCESS_CPUTIME_ID。
- 需包含头文件:
#include <time.h></time.h> - 调用前声明
struct timespec ts;,然后clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts); - 结果单位是秒 + 纳秒,合并成 double 秒:
double sec = ts.tv_sec + ts.tv_nsec / 1e9; - 该调用在大多数 Linux 发行版上可用,但 glibc 版本低于 2.17 可能不支持
Windows 下用 GetProcessTimes() 获取进程内核/用户态时间
Windows 没有直接等价于 CLOCK_PROCESS_CPUTIME_ID 的单一调用,必须用 GetProcessTimes() 分别读取内核态和用户态时间,再相加才是总 CPU 时间。
容易忽略的关键点:返回的 FILETIME 是 100 纳秒为单位的 64 位整数,不能直接当毫秒用;且必须用 ULARGE_INTEGER 转换才能安全计算。
- 需要
#include <windows.h></windows.h> - 调用时传入当前进程句柄:
GetCurrentProcess() - 四个
FILETIME*参数中,后两个(lpKernelTime,lpUserTime)才有效,前两个(创建/退出时间)一般不用 - 转换示例:
ULARGE_INTEGER kernel, user; kernel.QuadPart = ftKernel.dwLowDateTime | ((ULONGLONG)ftKernel.dwHighDateTime ,然后除以 <code>1e7得秒
跨平台封装要注意的兼容性陷阱
不要试图用 std::chrono::steady_clock::now() 替代——它测的是单调时钟流逝,和进程生命周期无关;也不要用 std::clock(),它在不同平台语义模糊(POSIX 要求是 CPU 时间,但 Windows 上常退化为 wall-clock)。
真正的跨平台方案只能条件编译,且必须区分“CPU 时间”和“运行时长”。如果业务逻辑实际需要的是从启动到现在的挂钟时间(比如超时控制),那就该用 std::chrono::system_clock 记录启动时刻,而非查进程时间。
- Linux 和 macOS 都支持
CLOCK_PROCESS_CPUTIME_ID,但 macOS 的clock_gettime是较晚版本才加入,旧系统需 fallback 到getrusage(RUSAGE_SELF, ...) - Windows 上
GetProcessTimes()在所有现代版本都稳定,但返回值是 100ns 单位,误当成毫秒会导致时间小 10000 倍 - 多线程程序中,
CLOCK_PROCESS_CPUTIME_ID统计的是整个进程所有线程的 CPU 时间总和,不是单线程的
为什么 ps 或 top 显示的时间和你代码算的不一致?
终端命令如 ps -o etime,pid 显示的是“elapsed time”(自启动至今的挂钟秒数),而 ps -o cputime 显示的才是 CPU 时间——但它默认格式化为 MM:SS,会截断毫秒、四舍五入,且不同 ps 实现对“是否包含子进程”的处理也不同。
调试时最稳妥的方式是:用同一套逻辑(比如都调 clock_gettime)在代码里打点,和外部工具比对;不要依赖 ps 输出的可读格式做精度验证。
-
ps -o pid,etime,cputime -p $PID可同时看挂钟与 CPU 时间,便于交叉验证 - 若发现代码结果比
ps小很多,检查是否用了CLOCK_MONOTONIC或忘了把纳秒部分转成秒 - 容器环境(如 Docker)中,
CLOCK_PROCESS_CPUTIME_ID仍有效,但ps显示可能受 cgroup CPU 限制造成统计偏差
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











