C++如何获取当前进程的启动CPU耗时 _ GetProcessTimes实战【实战】
作者:水悠悠予安
时间:2026-07-06
浏览:0
不能。要给出最直接的结论:不能。这也是很多开发者刚接触这个函数时最容易踩的坑。 `GetProcessTimes` 记录的,是进程自创建以来,在内核态和用户态下累积占用的 CPU 时间,单位是 100 纳秒。它既不是从“启动到现在”的 Wall-clock(挂钟)耗时,更不是“启动那一瞬间”的 CP
不能。要给出最直接的结论:不能。这也是很多开发者刚接触这个函数时最容易踩的坑。
`GetProcessTimes` 记录的,是进程自创建以来,在内核态和用户态下累积占用的 CPU 时间,单位是 100 纳秒。它既不是从“启动到现在”的 Wall-clock(挂钟)耗时,更不是“启动那一瞬间”的 CPU 开销。冷启动阶段的初始化开销——比如 DLL 加载、TLS 初始化、CRT 构造——这些虽然发生在用户态代码正式执行之前,但同样会被计入 `lpUserTime` 和 `lpKernelTime`。问题是,你没法把它们单独拎出来。所以,用它来度量“启动性能”,从一开始就找错了方向。
本文内容来源于互联网,如有侵权请联系删除。

GetProcessTimes 的正确用法:获取累计 CPU 时间
如果目标就是获取 CPU 占用时间,那它没问题。但调用前有几个前置条件必须明确: - 打开目标进程时,需要 `PROCESS_QUERY_INFORMATION` 权限。当前进程可以直接用 `GetCurrentProcess()`,省心。 - 返回的 `FILETIME` 是 64 位整数,单位 100 纳秒。直接看很懵,需要手动转成毫秒或秒。 - 即便进程已经退出了,只要句柄仍然有效,`GetProcessTimes` 依然能返回历史数据,不过值不会再变化了。 来个最典型的用法:获取当前进程自启动以来的累计 CPU 时间。FILETIME ftCreate, ftExit, ftKernel, ftUser;
if (GetProcessTimes(GetCurrentProcess(), &ftCreate, &ftExit, &ftKernel, &ftUser)) {
ULARGE_INTEGER uiKernel = { ftKernel.dwLowDateTime, ftKernel.dwHighDateTime };
ULARGE_INTEGER uiUser = { ftUser.dwLowDateTime, ftUser.dwLowDateTime };
DWORD64 total_ms = (uiKernel.QuadPart + uiUser.QuadPart) / 10000; // 转毫秒
}
真正想测“启动到此刻”的 Wall-clock 时间,该怎么办?
如果你的目标是知道进程从操作系统开始调度执行(也就是进入入口点那一刻)到当前时刻,究竟过去了多长时间,那得换个思路。把 `GetProcessTimes` 里的 `lpCreationTime` 和 `GetSystemTimeAsFileTime` 结合起来: - `lpCreationTime` 是进程被创建的精确系统时间戳(UTC 格式,精度不错)。 - 用 `GetSystemTimeAsFileTime` 拿到当前时间,两者相减,就是真实的运行时间。 **值得留意的是**:这个差值里面包含了进程所有的挂起、等待和 I/O 阻塞时间——它反映的是 Wall-clock 时长,而不是 CPU 占用时长。另外,别把 `lpCreationTime` 理解成“启动完成时间”:它仅仅是内核创建 EPROCESS 对象的时间点,比 `main()` 函数开始执行还要早。不过话说回来,对绝大多数应用场景而言,这个时间点已经足够有参考价值了。实操中容易忽略的兼容性与精度陷阱
`GetProcessTimes` 在 Windows XP SP2 及之后的系统中都可以用,但有两处细节在实际编码里经常让人翻车: - 32 位程序在 WoW64 下调用时,`FILETIME` 本身的数值没有问题。但很多人在手动拼接 `dwLowDateTime` 和 `dwHighDateTime` 时,习惯用 `ULARGE_INTEGER` 的 `.LowPart` 字段赋值,导致高位数据丢失。这个坑很隐蔽。 - 两次调用间隔如果极端短,`lpKernelTime` 和 `lpUserTime` 可能完全没有变化。原因在于 Windows 内核只在调度周期(通常约 15ms)内更新这些计数器,它并不是实时的采样机制。 - 还有一个极罕见的场景:如果进程刚启动,还没触发任何线程调度(比如卡在 loader lock 里),那么首次调用 `GetProcessTimes` 返回的 `FILETIME` 可能是全 0。 如果真的需要在“启动性能分析”这种场景里拿到精细数据,建议直接用 ETW(Event Tracing for Windows)去捕获 `ImageLoad`、`ProcessStart`、`ThreadStart` 等事件。`GetProcessTimes` 的定位本来就是粗粒度的监控手段,用它来做性能调优,精度和维度都不太够。
作者最新文章
灵活计算器
2026-09-16 17:45
苹果折叠屏iPhone预计售价是多少
2026-09-14 13:44
OpenAI GPT-6 Astra 自主通关《传送门》:技术原理与实验成本解析
2026-09-08 19:08
苹果与铠侠签署NAND长期供应协议:3-5年长约与不设价格上限背后的供应链战略
2026-09-08 16:58
PDF转PPT操作指南:在线、本地与批量转换及结果核对
2026-09-04 15:04
热门文章
更多
精品专题
更多
Mac软件
更多
WINDOWS
更多


































