应使用操作系统内核接口获取进程CPU时间:Windows调用GetProcessTimes,POSIX系统可用clock、clock_gettime(CLOCK_PROCESS_CPUTIME_ID)或getrusage;各方法精度、适用场景及注意事项不同。

如果您需要在C++程序中精确获取当前进程已消耗的CPU时间,而非挂钟时间,则需调用操作系统提供的内核级接口。Windows平台下GetProcessTimes可返回进程的内核态与用户态CPU时间,POSIX系统则依赖clock或clock_gettime等函数。以下是实现该目标的多种方法:
一、使用Windows API GetProcessTimes
该函数通过查询内核中进程对象的KPROCESS结构体,直接读取已累计的内核时间与用户时间(单位为100纳秒),精度高且不依赖线程调度状态。
1、包含头文件#include 和#include ;
2、调用GetCurrentProcess()获取当前进程伪句柄;
3、声明四个FILETIME变量分别接收创建时间、退出时间、内核时间、用户时间;
4、调用GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser);
5、将ftKernel和ftUser转换为64位整数后除以10000,得到毫秒级CPU时间;
6、将两部分相加即得总CPU时间:注意:此值不含子进程时间,仅限当前进程自身。
二、使用POSIX clock函数
clock()返回自进程启动以来的处理器时间,其底层通常映射至CLOCK_PROCESS_CPUTIME_ID或调用getrusage(RUSAGE_SELF, ...),但标准行为受CLOCKS_PER_SEC限制,精度可能仅为10ms量级。
1、包含头文件#include ;
2、在代码起始位置调用clock_t start = clock();;
3、在需测量处再次调用clock_t end = clock();;
4、计算差值:double cpu_ms = (double)(end - start) * 1000.0 / CLOCKS_PER_SEC;;
5、注意:该函数在多线程环境中返回的是所有线程累计CPU时间,非单线程独占值。
三、使用clock_gettime与CLOCK_PROCESS_CPUTIME_ID
该方法绕过clock()的抽象层,直接向内核请求进程级高精度CPU时间,Linux下通常基于vvar页实现,开销极低,精度可达纳秒级。
1、包含头文件#include ;
2、声明struct timespec ts;;
3、调用clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);;
4、将ts.tv_sec * 1000000000LL + ts.tv_nsec转换为纳秒总数;
5、多次调用可做差值计算区间CPU耗时;
6、注意:该时钟不随系统时间调整而变化,仅单调递增,且在进程fork后子进程拥有独立计数器。
四、使用getrusage获取详细资源使用数据
getrusage()提供比clock_gettime更细粒度的信息,包括用户态/内核态时间分离、页面错误次数、信号接收数等,适用于深度性能分析场景。
1、包含头文件#include ;
2、声明struct rusage usage;;
3、调用getrusage(RUSAGE_SELF, &usage);;
4、从usage.ru_utime和usage.ru_stime中提取tv_sec与tv_usec字段;
5、转换为微秒并求和:uint64_t total_us = usage.ru_utime.tv_sec * 1000000ULL + usage.ru_utime.tv_usec + usage.ru_stime.tv_sec * 1000000ULL + usage.ru_stime.tv_usec;;
6、注意:该调用在某些容器或cgroup受限环境中可能被截断或返回零值。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











