Qt获取CPU使用率及内存占用大小

Qt 获取 CPU 使用率及内存占用大小

文章目录

  • Qt 获取 CPU 使用率及内存占用大小
    • 一、简介
    • 二、关键函数
      • 2.1 获取当前运行程序pid
      • 2.2 通过pid获取运行时间
      • 2.3 通过pid获取内存大小
    • 三、具体实现
    • 五、写在最后

一、简介

近期在使用软件的过程中发现一个有意思的东西。如下所示:

在这里插入图片描述

该软件可以显示 CPU 使用率及内存大小和内存使用率。感觉比较有意思,于是就想着能不能通过 Qt 自己实现一套这样的东西,这也是本文的由来。

那么,言归正传,本文将介绍 如何使用 Qt 获取当前软件的 CPU 使用率及内存大小。本文适合对 Qt 有一些基础的朋友,对于一些简单的地方我不会过多赘述,望谅解!!!

另外,本文阐述方法不适用于 Linux,需要注意!!!

首先,我使用的环境如下所示:

  • Windows 10 x64
  • Qt 5.12.3

二、关键函数

本文专注于解决获取 Qt 当前运行程序的 CPU 使用率及内存大小,因此本文通过获取当前运行程序 pid 的形式获取运行时间,通过运行时间计算得到 CPU 使用率。

2.1 获取当前运行程序pid

Qt 中,可以通过如下所示的语句获取当前程序 PID

QApplication::applicationPid();

2.2 通过pid获取运行时间

首先,需要打开进程句柄,需要使用到如下所示的函数:

HANDLE OpenProcess(DWORD dwDesiredAccess,  BOOL  bInheritHandle,   DWORD dwProcessId       
);

其中三个参数意义如下所示:

  • dwDesiredAccess: 进程访问权限
  • bInheritHandle: 是否允许子进程继承此句柄,通常设为 FALSE
  • dwProcessId: 目标进程的 PID(进程标识符)

返回值意义如下所示:

  • 成功:返回进程句柄(HANDLE
  • 失败:返回 NULL,需调用 GetLastError() 获取错误码

更详细的解释在官方网站:OpenProcess 函数 (processthreadsapi.h) - Win32 apps | Microsoft Learn

如若链接点击无法跳转,可自行复制打开:

  • https://learn.microsoft.com/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess

其次,我们需要通过 PID 获取运行时间信息,需要使用到如下所示的函数:

BOOL GetProcessTimes(HANDLE     hProcess,LPFILETIME lpCreationTime,LPFILETIME lpExitTime,LPFILETIME lpKernelTime,LPFILETIME lpUserTime
);

其参数意义如下所示:

  • hProcess: 进程句柄
  • lpCreationTime: 进程的创建时间
  • lpExitTime: 进程的退出时间
  • lpKernelTime: 内核模式(如系统调用)下消耗的 CPP 时间
  • lpUserTime: 用户模式(应用程序代码)下消耗的 CPU 时间

返回参数意义如下所示:

  • 成功:返回 TRUE(非零值)
  • 失败:返回 FALSE(零值),需调用 GetLastError() 获取错误码

更详细的解释在官方网站:getProcessTimes 函数 (processthreadsapi.h) - Win32 apps | Microsoft Learn

如若链接点击无法跳转,可自行复制打开:

  • https://learn.microsoft.com/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocesstimes

2.3 通过pid获取内存大小

获取进程使用内存大小,需要使用如下所示函数:

BOOL GetProcessMemoryInfo(HANDLE            Process,         PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD             cb               
);

其参数意义如下所示:

  • Process: 进程句柄
  • ppsmemCounters: 指向 PROCESS_MEMORY_COUNTERS 结构的指针,用于接收内存统计信息
  • cb: 结构体大小,通常设为 sizeof(PROCESS_MEMORY_COUNTERS)

返回参数意义如下所示:

  • 成功:返回 TRUE(非零值)
  • 失败:返回 FALSE(零值),需调用 GetLastError() 获取错误码

其中需要注意的是 PROCESS_MEMORY_COUNTERS 结构体,其包含如下所示的成员参数:

typedef struct _PROCESS_MEMORY_COUNTERS {DWORD  cb;                   // 结构体大小DWORD  PageFaultCount;       // 页面错误次数SIZE_T PeakWorkingSetSize;   // 工作集峰值(物理内存)SIZE_T WorkingSetSize;       // 当前工作集大小SIZE_T QuotaPeakPagedPoolUsage; // 分页池配额峰值SIZE_T QuotaPagedPoolUsage;      // 当前分页池配额SIZE_T QuotaPeakNonPagedPoolUsage; // 非分页池配额峰值SIZE_T QuotaNonPagedPoolUsage;    // 当前非分页池配额SIZE_T PagefileUsage;        // 页面文件使用量SIZE_T PeakPagefileUsage;     // 页面文件使用峰值
} PROCESS_MEMORY_COUNTERS;

更详细的解释在官方网站:getProcessMemoryInfo 函数 (psapi.h) - Win32 apps | Microsoft Learn

如若链接点击无法跳转,可自行复制打开:

  • https://learn.microsoft.com/zh-cn/windows/win32/api/psapi/nf-psapi-getprocessmemoryinfo

通过上述三个步骤即可轻松获取当前运行程序的 CPU 使用率及内存大小。


三、具体实现

Qt 中推荐在线程中计算获取这些信息。因为我们计算方法每 1s 获取一次时间,计算与前 1s 时间的差值得到 CPU 占用率。如果不适用线程,将会阻塞主线程的执行。

这里我给出示例:

  • cpumontior.h

    #ifndef CPUMONTIOR_H
    #define CPUMONTIOR_H#include "windows.h"
    #include <QObject>
    #include <QThread>
    #include "psapi.h"
    #include <QtMath>class CpuMontior : public QThread
    {Q_OBJECT
    public:explicit CpuMontior(DWORD pid, QObject *parent = nullptr);void setDec(int dec) {this->dec = dec;}protected:void run() override;private:DWORD pid;int dec;// 封装转换函数static ULONGLONG filetimeToULONGLONG(const FILETIME *ft) {ULARGE_INTEGER uli;uli.LowPart = ft->dwLowDateTime;uli.HighPart = ft->dwHighDateTime;return uli.QuadPart;}// bytes 单位转换QString changeFileSize(qint64 fileSize){QStringList units;units << "B" << "KB" << "MB" << "GB" << "TB" << "PB";double mod  = 1024.0;double size = fileSize;//qDebug() << size;int i = 0;long rest = 0;while (size >= mod && i < units.count()-1 ){rest= static_cast<long>(size) % static_cast<long>(mod);size /= mod;i++;}QString szResult = QString::number(qFloor(size));if( rest > 0){szResult += QString(".") + QString::number(rest).left(this->dec);}szResult += units[i];return  szResult;}signals:/* 使用率信息 */void usageInfoSignal(QString cpuUsage, QString memUsage);public slots:
    };#endif // CPUMONTIOR_H
  • cpumontior.cpp

    #include "cpumontior.h"
    #ifdef QT_DEBUG
    #include <QDebug>
    #endif/*!*  @File        : cpumontior.cpp*  @Brief       : 构造函数*  @Details     : None*  @Param       : void*  @Return      : void*  @Author      : Liu Jiahao*  @Date        : 2025-03-28 14:18:10*  @Version     : v1.1*  @Copyright   : Copyright By Liu Jiahao, All Rights Reserved**/
    CpuMontior::CpuMontior(DWORD pid, QObject *parent) :QThread(parent), pid(pid), dec(2)
    {}/*!*  @File        : cpumontior.cpp*  @Brief       : 工作函数*  @Details     : None*  @Param       : void*  @Return      : void*  @Author      : Liu Jiahao*  @Date        : 2025-03-28 14:19:12*  @Version     : v1.1*  @Copyright   : Copyright By Liu Jiahao, All Rights Reserved**/
    void CpuMontior::run()
    {// 获取系统资源信息HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);if (!hProcess) return;FILETIME creationTime, exitTime, kernelTime, userTime;while (!isInterruptionRequested()) {// 第一次采样if (!GetProcessTimes(hProcess, &creationTime, &exitTime, &kernelTime, &userTime)) {break;}ULONGLONG kernel1 = filetimeToULONGLONG(&kernelTime);ULONGLONG user1 = filetimeToULONGLONG(&userTime);msleep(1000); // 每秒更新一次// 第二次采样if (!GetProcessTimes(hProcess, &creationTime, &exitTime, &kernelTime, &userTime)) {break;}ULONGLONG kernel2 = filetimeToULONGLONG(&kernelTime);ULONGLONG user2 = filetimeToULONGLONG(&userTime);// 计算差值ULONGLONG totalTime = (kernel2 - kernel1) + (user2 - user1);double cpuUsage = (totalTime / 10000.0) / 100.0; // 转换为百分比// 内存使用率PROCESS_MEMORY_COUNTERS pmc;qint64 memoryUsage = 0;if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {memoryUsage = static_cast<qint64>(pmc.WorkingSetSize); // 单位:字节}// 通过信号发送emit usageInfoSignal(QString::number(cpuUsage, 'f', this->dec) + "%", changeFileSize(memoryUsage));}
    #ifdef QT_DEBUGqDebug() << "quit thread";
    #endifCloseHandle(hProcess);
    }

增加 UI 进行显示后,效果如下所示:

在这里插入图片描述

可以说,跟我开头放的那个图区别不大。具体的 UI 设计这里不进行赘述,大家可以自行构建。我在函数中使用了 emit usageInfoSignal(QString::number(cpuUsage, 'f', this->dec) + "%", changeFileSize(memoryUsage)); 发送信号,大家可以根据这个信号 connect 槽函数进行实现。


五、写在最后

本文介绍了 如何使用 Qt 获取当前软件的 CPU 使用率及内存大小

题外话,现在觉得 AI 已经可以解决大部分遇到的问题,本文代码部分也借助了 AI 帮助,所有功能并非我原创。其实我也很惋惜,大家可以自行通过 AI 解决这些问题,就不需要在网上到处搜索,那我写博文似乎也失去了意义… 人工智能的发展不是坏事,只是改变了一些我们思考问题、解决问题的习惯。同时我也并不觉得 csdn 这个平台有多好,也未经过我同意擅自将我的文章设置为仅VIP可见,这与我初心相悖。随着工作繁忙,也很少有时间继续写下去…渐渐地也没有了动力。下次更新不知道是什么时候,希望读者海涵!

欢迎广大读者提出问题以及修改意见,本人看到后会给予回应,欢迎留言,后续会逐步进行开源!!!
另外,由于文章是作者手打的文字,有些地方可能文字会出错,望谅解,也可私信联系我,我对其进行更改。

  • 个人CSDN账号:刘梓谦_-CSDN博客

  • Gitee:刘佳豪 (liu-jiahaohappy) - Gitee.com

  • GitHub:Jiahao-Liu29 (github.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/904778.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

期刊论文写作注意点

下面给出关于期刊写作的几个关键注意点 一、摘要突出创新点 最重要的是论文的摘要&#xff0c;因为在论文送审的时候&#xff0c;编辑如果没有时间&#xff0c;最先看的就是摘要。摘要要写好。如果投的是顶刊&#xff0c;在摘要里面尽量不要写是在什么方法的基础上进行改进之类…

Swagger 3.0 中注解详细示例

Swagger 3.0 提供了丰富的注解来详细描述 API 的请求和响应。以下是一个使用 Operation、Parameter、RequestBody 和 ApiResponse 注解的示例&#xff0c;展示了如何设置请求头、请求参数、路径变量、请求体和响应体。代码中未使用 DTO 对象&#xff0c;而是使用 Map 来传递参数…

切比雪夫不等式专题习题解析

切比雪夫不等式专题习题解析 前言 本文为概率论习题集专栏的切比雪夫不等式专题习题解析,针对习题篇中的10道题目提供详细解答。希望通过这些解析帮助大家深入理解切比雪夫不等式的应用和意义。 一、基础概念题解析 习题1解析: 错误。切比雪夫不等式适用于任何具有有限方…

软件测试的概念

需求的概念 开发模型 测试模型 1. 什么是需求 在多数软件公司&#xff0c;会有两部分需求&#xff0c;⼀部分是⽤⼾需求&#xff0c;⼀部分是软件需求。 1.1 ⽤⼾需求 ⽤⼾需求&#xff1a;可以简单理解为甲⽅提出的需求&#xff0c;如果没有甲⽅&#xff0c;那么就是终端⽤⼾…

前端面试每日三题 - Day 29

这是我为准备前端/全栈开发工程师面试整理的第29天每日三题练习&#xff1a; ✅ 题目1&#xff1a;Web Components技术全景解析 核心三要素 Custom Elements&#xff08;自定义元素&#xff09; class MyButton extends HTMLElement {constructor() {super();this.attachShado…

StreamRL:弹性、可扩展、异构的RLHF架构

StreamRL&#xff1a;弹性、可扩展、异构的RLHF架构 大语言模型&#xff08;LLMs&#xff09;的强化学习&#xff08;RL&#xff09;训练正处于快速发展阶段&#xff0c;但现有架构存在诸多问题。本文介绍的StreamRL框架为解决这些难题而来&#xff0c;它通过独特设计提升了训…

LVGL的核心:lv_timer_handler

文章目录 &#x1f9e0; 一句话总结 LVGL 的运行核心&#xff1a;&#x1f501; 1. while(1) 主循环中的 lv_task_handler()⏱️ 2. lv_timer_handler() 定时器调度核心✅ 并发控制✅ 关键行为流程&#xff1a;&#x1f300; 任务执行逻辑&#xff1a;&#x1f9ee; 计算下一次…

【数据机构】2. 线性表之“顺序表”

- 第 96 篇 - Date: 2025 - 05 - 09 Author: 郑龙浩/仟墨 【数据结构 2】 文章目录 数据结构 - 2 -线性表之“顺序表”1 基本概念2 顺序表(一般为数组)① 基本介绍② 分类 (静态与动态)③ 动态顺序表的实现**test.c文件:****SeqList.h文件:****SeqList.c文件:** 数据结构 - 2 …

101 alpha——8 学习

alpha (-1 * rank(((sum(open, 5) * sum(returns, 5)) - delay((sum(open, 5) * sum(returns, 5)),这里我们操作符都明白&#xff0c;现在来看金融意义 金融意义 里层是这个 (sum(open, 5) * sum(returns, 5)) - delay((sum(open, 5) * sum(returns, 5)), 10 这里是两个相减…

auto推导类型原则

auto 是 C11 引入的类型自动推导关键字&#xff0c;它允许编译器根据表达式的类型来推导变量的确切类型。虽然使用 auto 可以让代码更简洁&#xff0c;但理解它的类型推导规则非常关键&#xff0c;尤其是在涉及指针、引用、const、模板等场景时。 ✅ 一、基本推导原则 auto x …

使用智能表格做FMEDA

一、优点 使用智能表格替代excel做FMEDA具备以下优势&#xff1a; 减少维护成本&#xff08;数据库关联&#xff0c;修改方便&#xff09;便于持续优化&#xff08;失效率分布&#xff0c;失效率模型可重复使用&#xff09;多人同步编写&#xff08;同时操作&#xff0c;同步…

IP协议.

IP 协议是互联网的核心协议&#xff0c;工作在网络层。它给网络中的设备分配唯一的 IP 地址&#xff0c;把上层数据封装成数据包&#xff0c;然后根据目的 IP 地址通过路由器等设备进行转发&#xff0c;实现数据在不同网络间的传输。它还能在必要时对数据包进行分片和重组&…

archlinux 详解系统层面

Arch Linux 深度解析&#xff1a;从设计哲学到系统架构 一、Arch Linux 概述&#xff1a;滚动发行的极客之选 Arch Linux 是一款以 滚动更新&#xff08;Rolling Release&#xff09; 为核心特性的 Linux 发行版&#xff0c;强调 轻量、灵活、高度可定制&#xff0c;旨在让用…

HTML8:媒体元素

视频和音频 视频元素 video 音频 audio <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>媒体元素学习</title> </head> <body> <!--音频和视频 src:资源路径 controls:控制条…

SpringBoot3集成Oauth2——1(/oauth2/token方法的升级踩坑)

备注&#xff1a;本文适用于你在SpringBoot2.7以前集成过oauth2&#xff0c;并且项目已经正式投入使用的情况&#xff0c;否则&#xff0c;我建议你直接学习或者找资料学习最新的oauth2集成&#xff0c;就不要纠结于老版本的oauth2。 原因&#xff1a;Spring Security 5.x和Sp…

笔记本电脑实现网线内网 + Wi-Fi外网同时使用的配置方案

1、同时连接两个网络‌ 插入网线连接内网&#xff0c;确保内网IP地址正常获取&#xff08;如10.143.88.x&#xff09;&#xff1b;连接Wi-Fi接入外网&#xff0c;确认可正常访问互联网&#xff08;如网关为192.168.8.1&#xff09;。 2、 记录关键网络参数‌ 内网网关&#…

从韦斯利・卡普洛看北斗星咨询公司的技术咨询引领之路

在科技与商业深度交融的时代&#xff0c;技术咨询公司扮演着举足轻重的角色&#xff0c;它们宛如连接技术创新与企业实际需求的桥梁&#xff0c;助力企业在复杂多变的市场环境中找准技术发展方向&#xff0c;实现可持续增长。《对话 CTO&#xff0c;驾驭高科技浪潮》的第 5 章聚…

首版次软件测试的内容有哪些?首版次软件质量影响因素是什么?

首版次软件测试不仅是简单的“找错”&#xff0c;更是系统地验证和评估软件各项功能和性能指标是否符合设计标准。 一、首版次软件测试常见的测试内容   1.功能测试&#xff1a;对照需求文档&#xff0c;确认功能模块是否按预期实现&#xff0c;用户操作流程是否顺畅。   …

从零开始的python学习(六)P86+P87+P88

本文章记录观看B站python教程学习笔记和实践感悟&#xff0c;视频链接&#xff1a;【花了2万多买的Python教程全套&#xff0c;现在分享给大家&#xff0c;入门到精通(Python全栈开发教程)】 https://www.bilibili.com/video/BV1wD4y1o7AS/?p6&share_sourcecopy_web&v…

从设计到开发,原型标注图全流程标准化

一、原型标注图是什么&#xff1f; 原型标注图&#xff08;Annotated Prototype&#xff09;是设计原型&#xff08;Prototype&#xff09;的详细说明书&#xff0c;通过图文结合的方式&#xff0c;将设计稿中的视觉样式、交互逻辑、适配规则等技术细节转化为开发可理解的标准…