C++中获取进程精确CPU内核时间片的四种方法:一、clock_gettime(CLOCK_THREAD_CPUTIME_ID)纳秒级线程CPU时间;二、解析/proc/[pid]/stat第14/15字段换算微秒级总CPU时间;三、getrusage(RUSAGE_SELF)跨平台微秒级统计;四、perf_event_open采集PERF_COUNT_SW_CPU_CLOCK事件达纳秒级精度。

如果您需要在C++程序中获取进程当前执行所占用的精确CPU内核时间片,以进行低开销、高精度的性能监控,则需绕过用户态时钟抽象,直接读取内核暴露的调度器级计时数据。以下是实现该目标的多种方法:
一、使用clock_gettime(CLOCK_THREAD_CPUTIME_ID, ...)
该方法通过POSIX时钟接口获取当前线程在CPU上实际执行的内核+用户态时间,精度通常达纳秒级,且不包含休眠、等待等非执行时间,是测量真实CPU时间片最标准的方式。
1、包含必要头文件:#include
2、声明 timespec 结构体变量用于接收结果:struct timespec ts;。
3、调用 clock_gettime 函数并传入 CLOCK_THREAD_CPUTIME_ID:clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);。
4、将秒与纳秒字段组合为纳秒总数:uint64_t nanos = ts.tv_sec * 1000000000ULL + ts.tv_nsec;。
二、读取/proc/[pid]/stat中的第14、15字段(utime与stime)
Linux内核通过/proc文件系统向用户空间导出每个进程的累计CPU时间,其中第14字段(utime)为用户态jiffies,第15字段(stime)为内核态jiffies,二者之和即为总CPU时间片消耗,结合系统HZ可换算为微秒级精度。
1、构造/proc/self/stat路径字符串:std::string path = "/proc/" + std::to_string(getpid()) + "/stat";。
2、以只读方式打开该文件并定位至第14个空格分隔字段起始位置。
3、使用 sscanf 或 std::istringstream 提取第14(utime)和第15(stime)字段的整数值:long utime, stime; sscanf(line.c_str(), "%*d %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %ld %ld", &utime, &stime);。
4、将 utime + stime 乘以系统jiffy粒度(通常为 1000000UL / sysconf(_SC_CLK_TCK) 微秒)得到微秒级总CPU时间。
三、使用getrusage(RUSAGE_SELF, ...)
getrusage 系统调用返回进程自启动以来的资源使用统计,其中 ru_stime 和 ru_utime 字段分别表示内核态与用户态累计时间,精度为微秒,适用于粗粒度但跨平台兼容性更高的场景。
1、声明 struct rusage 变量:struct rusage usage;。
2、调用 getrusage 并指定 RUSAGE_SELF:getrusage(RUSAGE_SELF, &usage);。
3、提取并转换时间:将 usage.ru_utime.tv_sec 与 usage.ru_utime.tv_usec 合并为用户态微秒数,同理处理 usage.ru_stime 获取内核态微秒数。
4、相加得总CPU微秒数:uint64_t total_us = (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) * 1000000ULL + usage.ru_utime.tv_usec + usage.ru_stime.tv_usec;。
四、利用perf_event_open系统调用采集PERF_COUNT_SW_CPU_CLOCK事件
该方法通过Linux perf子系统直接访问硬件或软件性能计数器,PERF_COUNT_SW_CPU_CLOCK提供每线程单调递增的CPU执行时间戳,具备极高精度(通常优于10纳秒),且不受系统时间调整影响。
1、定义 perf_event_attr 结构体并设置 type = PERF_TYPE_SOFTWARE、config = PERF_COUNT_SW_CPU_CLOCK、disabled = 1、exclude_kernel = 0、exclude_user = 0。
2、调用 perf_event_open 创建文件描述符:int fd = perf_event_open(&attr, 0, -1, -1, 0);。
3、启用计数器:ioctl(fd, PERF_EVENT_IOC_RESET, 0); ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);。
4、读取8字节计数值:uint64_t tsc; read(fd, &tsc, sizeof(tsc));。
5、关闭fd并重复采样以计算差值,所得即为两次调用间精确CPU执行时间(纳秒级)。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











