实时监测CPU和内存使用率 并 发送到企业微信机器人
项目背景:在评估软件资源使用率的时候,需要统计CPU和内存最大使用率,因此需要监测软件运行工程中的CPU和内存使用率的变化,并记录最大值
1.内存统计会比较简单,只需要查询电脑中最大内存,以及实时内存使用情况

1 #include <windows.h> 2 #include <stdio.h> 3 #include <conio.h> 4 #include<iostream> 5 double FileTimeToDouble(FILETIME* pFiletime) 6 { 7 return (double)((*pFiletime).dwHighDateTime * 4.294967296E9) + (double)(*pFiletime).dwLowDateTime; 8 } 9 10 double m_fOldCPUIdleTime; 11 double m_fOldCPUKernelTime; 12 double m_fOldCPUUserTime; 13 14 15 16 BOOL Initialize() 17 { 18 FILETIME ftIdle, ftKernel, ftUser; 19 BOOL flag = FALSE; 20 if (flag = GetSystemTimes(&ftIdle, &ftKernel, &ftUser)) 21 { 22 m_fOldCPUIdleTime = FileTimeToDouble(&ftIdle); 23 m_fOldCPUKernelTime = FileTimeToDouble(&ftKernel); 24 m_fOldCPUUserTime = FileTimeToDouble(&ftUser); 25 26 } 27 return flag; 28 } 29 30 int GetCPUUseRate() 31 { 32 int nCPUUseRate = -1; 33 FILETIME ftIdle, ftKernel, ftUser; 34 if (GetSystemTimes(&ftIdle, &ftKernel, &ftUser)) 35 { 36 double fCPUIdleTime = FileTimeToDouble(&ftIdle); 37 double fCPUKernelTime = FileTimeToDouble(&ftKernel); 38 double fCPUUserTime = FileTimeToDouble(&ftUser); 39 nCPUUseRate = (int)(100.0 - (fCPUIdleTime - m_fOldCPUIdleTime) / (fCPUKernelTime - m_fOldCPUKernelTime + fCPUUserTime - m_fOldCPUUserTime)*100.0); 40 m_fOldCPUIdleTime = fCPUIdleTime; 41 m_fOldCPUKernelTime = fCPUKernelTime; 42 m_fOldCPUUserTime = fCPUUserTime; 43 } 44 return nCPUUseRate; 45 } 46 int GetMemoryUsePercentage() 47 { 48 MEMORYSTATUSEX mstx; 49 mstx.dwLength = sizeof(mstx); 50 GlobalMemoryStatusEx(&mstx); 51 int iMemeryUsePercentage = mstx.dwMemoryLoad; 52 int iTotalPhysMB = mstx.ullTotalPhys / 1024 / 1024; 53 int iAvailPhysMB = mstx.ullAvailPhys / 1024 / 1024; 54 int iTotalPageFileMB = mstx.ullTotalPageFile / 1024 / 1024; 55 int iAvailPageFileMB = mstx.ullAvailPageFile / 1024 / 1024; 56 char LogBuff[128]; 57 memset(LogBuff, 0, 128); 58 //sprintf(LogBuff, "MemAvailPct=%d%% Phys=%d/%d PageFile=%d/%d", iMemeryUsePercentage, iAvailPhysMB, iTotalPhysMB, iAvailPageFileMB, iTotalPageFileMB); 59 //printf("%s\n", LogBuff); 60 return iMemeryUsePercentage; 61 } 62 63 64 int main() 65 { 66 int maxCPUUsePercentage = 0; 67 int maxMemoryUsePercentage = 0; 68 if (!Initialize()) 69 { 70 system("pause"); 71 return -1; 72 } 73 else 74 { 75 while(true) 76 { 77 Sleep(1000); 78 int CpuUseRate = int(GetCPUUseRate( 79 int MemoryUseRate = GetMemoryUsePercentage();; 80 if (CpuUseRate> maxCPUUsePercentage) 81 { 82 maxCPUUsePercentage = CpuUseRate; 83 } 84 85 if (MemoryUseRate > maxMemoryUsePercentage) 86 { 87 maxMemoryUsePercentage = MemoryUseRate; 88 } 89 90 std::cout << "当前CPU使用率: " << CpuUseRate << 91 " 最大CPU使用率: "<<maxCPUUsePercentage<< " 当前内存: " << MemoryUseRate << 92 " 最大内存:"<< maxMemoryUsePercentage << std::endl; 93 94 } 95 } 96 return 0; 97 }
2.CPU使用率更复杂
CPU:Cores, and Hyper-Threading
超线程(Hyper-Threading )
超线程是Intel最早提出一项技术,最早出现在2002年的Pentium4上。单个采用超线程的CPU对于操作系统来说就像有两个逻辑CPU,为此P4处理器需要多加入一个Logical CPU Pointer(逻辑处理单元)。
虽然采用超线程技术能同时执行两个线程,但它并不像两个真正的CPU那样,每个CPU都具有独立的资源。当两个线程都同时需要某一个资源时,其中一个要暂时停止,并让出资源,直到这些资源闲置后才能继续。因此超线程的性能并不等于两颗CPU的性能。
多核(multi-cores)
最开始CPU只有一个核(core),为了提高性能,引入了双核CPU,四核CPU等,双核CPU能同时执行两个线程。和超线程不同的是,双核CPU是实打实的有两个central processing units在一个CPU chip。
上图显示主板上有1个插槽(socket),这个插槽插着一个CPU,这个CPU有4个核(core),每个核都使用超线程技术,所以这台机器总共有8个逻辑核。
实现CPU使用率统计程序
某进程cpu使用率 = 该进程cpu时间 / 总cpu时间。
发送到企业微信机器人:
采用了个比较笨的办法:
将数值写入bat脚本,再启用bat脚本执行post命令。
ofstream out(filePath, ios::out | ios::trunc); if (!out.is_open()) { cout << "文件创建失败!" << endl; exit(0); } string res; stringstream ss; ss << tempMaxCpuRate; ss >> res; std::string batContext = ""; batContext.append("curl -H "); batContext.append("\"Content-Type: application/json\""); batContext.append(" -X POST -d \"{\\\"msgtype\\\": \\\"markdown\\\", \\\"markdown\\\": {\\\"content\\\": \\\""); batContext.append(hostName); /* std::string str = "计算已完成"; batContext.append(str);*/ batContext.append(":computation completed!\\\"}}\" \"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=------------------------\"");//key可以从企业微信机器人端获取 out << batContext; tempMaxCpuRate = 0; out.close(); QProcess p(NULL); p.setWorkingDirectory(QString::fromStdString(save_as)); QString command = QString::fromStdString(filePath); p.start(command); p.waitForFinished();
参考:
https://www.cnblogs.com/gatsby123/p/11127158.html
https://blog.csdn.net/fyxichen/article/details/50577580
https://blog.csdn.net/sz76211822/article/details/58599219
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!