0

0

C++如何快速获取进程的实时CPU占用率?(系统监控)

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-03-13 17:38:45

|

657人浏览过

|

来源于php中文网

原创

最可靠方法是两次采样/proc/[pid]/stat的utime+stime与/proc/stat的系统总jiffies,计算差值占比;分母应为逻辑核数×采样间隔或系统jiffies增量,而非开机时间。

c++如何快速获取进程的实时cpu占用率?(系统监控)

Linux下用 /proc/[pid]/stat 解析 CPU 时间最可靠

直接读取 /proc/[pid]/stat 是 Linux 上获取进程 CPU 占用率的底层方式,比 shell 命令或库封装更轻、更准、无额外进程开销。关键不是“读”,而是怎么算——CPU 占用率本质是「该进程在采样周期内占用的 CPU 时间占比」,必须做两次采样并结合系统总 jiffies 计算。

  • /proc/[pid]/stat 第 14、15 字段(utimestime)提取用户态 + 内核态总 tick 数;注意字段顺序固定,但需跳过括号内的命令名(可能含空格)
  • 同时读 /proc/stat 的第一行(cpu),累加前 4 个数字得到系统总 jiffies(user+nice+system+idle,不含 iowait 等)
  • 两次采样间隔建议 ≥200ms:太短会导致差值为 0;太长则实时性下降,且需注意 jiffies 是 uint64,但内核每秒更新频率有限(通常 100–1000Hz)
  • 别用 clock_gettime(CLOCK_PROCESS_CPUTIME_ID):它只返回本进程时间,无法和系统总时间对齐,算不出百分比

Windows 上必须用 GetProcessTimes() + 系统 uptime 差值

Windows 没有类似 /proc 的实时文件接口,GetProcessTimes() 返回的是 FILETIME(100ns 精度),但单次调用只能得累计值。要换算成占用率,必须和系统启动后总运行时间(uptime)联动计算。

  • 调用 GetProcessTimes() 得到 kernelTimeuserTime,合并为 total CPU time(单位:100ns)
  • GetTickCount64() 获取系统已运行毫秒数,再乘以 10000 转为 100ns 单位(⚠️注意:不能直接用 GetSystemTimeAsFileTime(),那是绝对时间,不是 uptime)
  • 两次采样间,进程 CPU 时间差 ÷ 系统 uptime 差 = 近似占用率;若进程被挂起,这个值会偏低,属正常行为
  • 权限问题常被忽略:对非自身进程调用 OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION) 就够了,无需 PROCESS_QUERY_INFORMATION(后者需要调试权限)

跨平台封装时,避免用 std::this_thread::sleep_for() 控制采样节奏

睡眠精度受系统调度影响极大:Linux 默认 timer resolution 是 10–15ms,Windows 可能更差。用 sleep_for(200ms) 实际可能停 230ms 或 280ms,导致分母(系统时间差)不准,最终 CPU% 波动剧烈甚至超 100%。

  • 改用单调时钟主动轮询:记录上一次采样时刻(std::chrono::steady_clock::now()),每次循环检查是否 ≥目标间隔,未到就 sleep_for(1ms) 再试
  • 不要把两次 utime+stime 直接相减当作“本次 CPU 时间”:如果进程刚被调度、还没执行完当前时间片,差值可能远小于真实消耗
  • 多线程进程的 CPU 时间是所有线程之和,/proc/[pid]/statGetProcessTimes() 都已包含,无需额外遍历线程

常见错误:top 显示 120% 但你的程序算出 95%,不是代码错

这是采样窗口和统计口径差异导致的。例如 top 默认每 3 秒刷新、显示最近 3 秒平均,而你可能按 1 秒间隔采样并立即计算——前者平滑,后者敏感。更关键的是:top 的 %CPU 是「相对于单个逻辑核」的,120% 表示它平均占用了 1.2 个核;而你的公式如果除以「系统总核数 × 时间」,结果自然偏低。

Rose.ai
Rose.ai

一个云数据平台,帮助用户发现、可视化数据

下载

立即学习C++免费学习笔记(深入)”;

  • 想对齐 top 行为?把分母改成「单核时间 × 采样间隔」:即 delta_process_jiffies / (sysconf(_SC_CLK_TCK) * interval_sec)
  • macOS 不适用本文方法:它没有 /proc,需用 libproc + task_info(),且返回的是毫秒级近似值,精度和语义都不同
  • 容器环境(如 Docker)中,/proc/[pid]/stat 仍有效,但系统总 jiffies 来自宿主机,而进程受 cgroup CPU quota 限制——此时你的百分比反映的是「在配额内跑满的程度」,不是物理核占用

实际写的时候,最易被绕进去的是“该拿什么当分母”。不是系统总时间,不是开机时间,而是“这段时间里,整个系统理论上最多能提供多少 CPU 时间”——它等于(逻辑核数 × 采样间隔),或者等价于(系统总 jiffies 增量)。少盯一眼,结果就飘了。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1948

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

658

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2401

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

47

2026.01.19

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

765

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

377

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

32

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

30

2026.01.21

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11.3万人学习

C 教程
C 教程

共75课时 | 5.4万人学习

C++教程
C++教程

共115课时 | 21.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号