使用PDH性能计数器(Windows)获取CPU使用率、可用物理内存、上传/下载速率、磁盘读写速率
最近要写一个windows下的监控客户端,需要收集计算机的一些信息。
其中CPU使用率、可用物理内存(用于计算内存使用率)、上传/下载速率、磁盘读写速率,都需要实时的。各种资料查询之后,决定使用pdh性能计数器来做。
下面直接贴实现函数。需要注意的有几点:1、首先需要导入pdh的lib库;2、注意接收pdh函数的返回值,判断程序运行状态;3、需求是要收集实时值,所以开一个线程,每秒调用一次实现函数即可;4、在通过pdh函数获取数据时,需要延时,否则会导致数据不准确;5、网速的查询是特别的,因为查询语句中会带有网络适配器的名称,也就是网卡名,对于多张网卡的情况,需要自行确定走的是哪个网卡。而不同计算机名称都会不同,所以将该变量放在配置文件中,以保证代码的一致。
还有个疑问,不知道为什么PdhCollectQueryData()需要调用两次,调用一次收集会失败。
最后收集的数据放在结构体中,并压入队列,等待上传到服务端。目前实现是每收集到一组数据就上传一次,当然也可以通过链表长度和时间来控制上传频率。
由于数据最终是以二进制流的方式上传到服务端,所以结构体定义成了类的形式,带了打包、解包函数。如下:
//用于保存搜集的实时数据
class RealtimeData : public MY_OBJECT
{
public:int iCPUUsage; // CPU使用率double dbDownloadSpeed; // 下载速率double dbUploadSpeed; // 上传速率int iMemory; // 可用内存(M)double dbDiskRead; // 磁盘读速率double dbDiskWrite; // 磁盘写速率INT64 time; // 本次搜集的本机时间public://把内部结构打包成char*格式的扁平格式//外部需要自行delete它传出来的char*,用delete []来释放//参数 char * pDataBuf 如果不为 NULL, 则序列化后的结果会保存到这个缓冲指向的空间virtual char * Package_( char * pDataBuf = NULL ) const;//把Package打包的结果反打包,并还原到本类自身//返回处理的字节数,返回-1表示处理失败virtual int UnPackage_( const char * Stream );//获得Package打包后字节流的长度virtual int GetPackageLength_() const;
};//搜集的实时数据的链表,用于发送
class RealtimeDataList : public MY_OBJECT
{
public:CMyStdVector<RealtimeData> vtRealtimeDataList;public://把内部结构打包成char*格式的扁平格式//外部需要自行delete它传出来的char*,用delete []来释放//参数 char * pDataBuf 如果不为 NULL, 则序列化后的结果会保存到这个缓冲指向的空间virtual char * Package_( char * pDataBuf = NULL ) const;//把Package打包的结果反打包,并还原到本类自身//返回处理的字节数,返回-1表示处理失败virtual int UnPackage_( const char * Stream );//获得Package打包后字节流的长度virtual int GetPackageLength_() const;
};
PDH数据收集实现函数如下:
BOOL CMonitorClientWorkTread::GatherRealtimeData()
{HQUERY query; double dbVal;long iVal;PDH_STATUS status = PdhOpenQuery(NULL, NULL, &query); if (ERROR_SUCCESS != status) { printf("性能计数器查询,打开失败。");return FALSE;}HCOUNTER cntCPU, cntNetDownload, cntNetUpload; HCOUNTER cntMemory, cntDiskRead, cntDiskWrite;char strNetWork[MAX_PATH];GetPrivateProfileString("data", "network", "", strNetWork, MAX_PATH, m_strConfigDir); //从配置文件中获取网络适配器名称,用于拼接PDH查询字符串status = PdhAddCounter(query, _TEXT("\\Processor(_Total)\\% Processor Time"), NULL, &cntCPU); //%号和P之间要有空格char strNetReveive[MAX_PATH], strNetSent[MAX_PATH];sprintf_s(strNetReveive, "\\Network Interface(%s)\\Bytes Received/sec", strNetWork);sprintf_s(strNetSent, "\\Network Interface(%s)\\Bytes Sent/sec", strNetWork);status = PdhAddCounter(query, strNetReveive, NULL, &cntNetDownload);status = PdhAddCounter(query, strNetSent, NULL, &cntNetUpload);status = PdhAddCounter(query, _TEXT("\\Memory\\Available MBytes"), NULL, &cntMemory);status = PdhAddCounter(query, _TEXT("\\PhysicalDisk(_Total)\\Disk Read Bytes/sec"), NULL, &cntDiskRead);status = PdhAddCounter(query, _TEXT("\\PhysicalDisk(_Total)\\Disk Write Bytes/sec"), NULL, &cntDiskWrite);if (ERROR_SUCCESS != status) { printf("性能计数器查询,查询添加失败。");return FALSE;} PdhCollectQueryData(query); Sleep(500); //这里要有延时不然结果相当不准确 PdhCollectQueryData(query); if(ERROR_SUCCESS != status) { printf("性能计数器查询,数据请求失败。");return FALSE; } PDH_FMT_COUNTERVALUE pdhValue; DWORD dwValue; RealtimeData realtimeData;status = PdhGetFormattedCounterValue(cntCPU, PDH_FMT_DOUBLE, &dwValue, &pdhValue); if(ERROR_SUCCESS != status) { printf("性能计数器查询,获取数据失败,CPU使用率。");return FALSE; }else{dbVal = pdhValue.doubleValue; realtimeData.iCPUUsage = (int)(dbVal+0.5);}status = PdhGetFormattedCounterValue(cntNetDownload, PDH_FMT_DOUBLE, &dwValue, &pdhValue);if(ERROR_SUCCESS != status) { printf("性能计数器查询,获取数据失败,下载速率。");return FALSE; }else{dbVal = pdhValue.doubleValue; realtimeData.dbDownloadSpeed = (double)((dbVal/(1024*1.0f)));}status = PdhGetFormattedCounterValue(cntNetUpload, PDH_FMT_DOUBLE, &dwValue, &pdhValue);if(ERROR_SUCCESS != status) { printf("性能计数器查询,获取数据失败,上传速率。");return FALSE; }else{dbVal = pdhValue.doubleValue; realtimeData.dbUploadSpeed = (double)((dbVal/(1024*1.0f)));}status = PdhGetFormattedCounterValue(cntMemory, PDH_FMT_LONG, &dwValue, &pdhValue);if(ERROR_SUCCESS != status) { printf("性能计数器查询,获取数据失败,可用物理内存。");return FALSE; }else{iVal = pdhValue.longValue; realtimeData.iMemory = iVal;}status = PdhGetFormattedCounterValue(cntDiskRead, PDH_FMT_DOUBLE, &dwValue, &pdhValue);if(ERROR_SUCCESS != status) { printf("性能计数器查询,获取数据失败,磁盘读速率。");return FALSE; }else{dbVal= pdhValue.doubleValue; realtimeData.dbDiskRead = (double)((dbVal/(1024*1.0f)));}status = PdhGetFormattedCounterValue(cntDiskWrite, PDH_FMT_DOUBLE, &dwValue, &pdhValue);if(ERROR_SUCCESS != status) { printf("性能计数器查询,获取数据失败,磁盘写速率。");return FALSE; }else{dbVal = pdhValue.doubleValue; realtimeData.dbDiskWrite = (double)((dbVal/(1024*1.0f)));}PdhRemoveCounter(cntCPU);PdhRemoveCounter(cntNetDownload);PdhRemoveCounter(cntNetUpload);PdhCloseQuery(query);//将收集到的实时数据保存到链表中time (&realtimeData.time);/*struct tm *st;st = localtime(&realtimeData.time);*/m_realtimeDataList.vtRealtimeDataList.push_back(realtimeData);//将链表数据发送到服务端MsgHead head;head.nMsgLenght = m_realtimeDataList.GetPackageLength();head.nMsgType = MT_REALTIMEDATA;CMessageItem * pItem = gMsgItemObtain.GetNewMsgItem(); pItem->SetMessageCode( HS_SEND_NETWORK_DATA );pItem->SetAutoReduceRefAfterMsgLoop( true );// 消息头pItem->SetData(&head,sizeof(head));char *p;p = m_realtimeDataList.Package();pItem->AppendDate(p,head.nMsgLenght);gGlobalEnvManager.PostMessage( HSDLL_THREAD_NAME, pItem );delete p;m_realtimeDataList.vtRealtimeDataList.pop_back();return TRUE;
}
使用PDH性能计数器(Windows)获取CPU使用率、可用物理内存、上传/下载速率、磁盘读写速率相关推荐
- Linux和windows下minio+springboot实现文件服务器上传下载和nginx反向代理
1 minio服务器的安装 在下载minio.exe文件: windows安装minio服务器:MinIO | Code and downloads to create high performanc ...
- python采集修改原创_python应用系列教程——python中ftp操作:连接、登录、获取目录,重定向、上传下载,删除更改...
python中ftp操作: ftp=FTP() #设置变量 ftp.set_debuglevel(2) #打开调试级别2,显示详细信息 ftp.connect("IP"," ...
- ssm上传文件获取路径_SSM实现图片上传下载功能
0. 基本步骤框架搭建 实现带图片上传的注册功能 实现下载功能 1. 框架搭建 Step1 创建开发项目 创建基础MVC包结构:controller.service.mapper.pojo Step2 ...
- python应用系列教程——python中ftp操作:连接、登录、获取目录,重定向、上传下载,删除更改
全栈工程师开发手册 (作者:栾鹏) python教程全解 python中ftp操作: ftp=FTP() #设置变量 ftp.set_debuglevel(2) #打开调试级别2,显示详细信息 ftp ...
- 使用PSFTP进行Windows与Linux远程服务器的上传下载
1.下载: 2.使用 2.1 双击即可使用 2.2 使用规范 我说点常用的,我们用PSFTP主要也就是上传和下载.PSFTP是PuTTY SFTP客户端,用于本地与服务器间安全传输文件(使用SSH连接 ...
- Windows获取CPU、内存和磁盘使用率脚本
获取CPU使用率脚本(vbs),另存为cpu.vbs: On Error Resume Next Set objProc = GetObject("winmgmts:\\.\root\cim ...
- java获取网络带宽_Linux Java 获取CPU使用率,内存使用率,磁盘IO,网络带宽使用率等等...
/** * 获取带宽上传下载速度 * @return */ public String getNetWorkSpeed() { boolean result = false; String detai ...
- Qt linux获取cpu使用率、内存、网络收发速度、磁盘读写速度、磁盘剩余空间等
Qt linux获取cpu使用率.内存.网络收发速度.磁盘读写速度.磁盘剩余空间等,实际上大部分都和qt无关的,用其他语言也可以获取. code: .h #ifndef RESOURCE_MINITO ...
- ios android cpu占用率,iPhone-iOS-从应用程序获取CPU使用率
iPhone-iOS-从应用程序获取CPU使用率 有谁知道如何获取应用程序的CPU使用率? 绝对有可能,因为应用商店中有一些可以显示它的应用程序(活动监视器触摸). 3个解决方案 74 votes 更 ...
最新文章
- IJCAI 2021 医药AI必读论文推荐
- 推荐一个妹子,播报汽车新闻
- 同事操作两个数据源保持事务一致_「微服务架构」微服务架构中的数据一致性...
- 5g时代计算机网络过时,5g云电脑 取代主机(5g时代云电脑会普及吗)
- 北航计算机组成原理课程设计-2020秋 PreProject-Logisim-Logisim仿真与调试应用与挑战
- linux下codeblock使用注意事项 (deepin)
- 2011年上半年国内优秀初创企业产品汇总
- Youtube油管视频类别标签列表
- fanuc机器人四边形编程_FANUC机器人编程与操作
- SpringIOC和DI简单总结
- xcode8 上传app到appStore 遇到 error ITMS90096
- 国际赛事证书,220G数据集开放下载|ACCV2022国际细粒度图像分析挑战赛开赛
- R配对样本t检验(PAIRED T-TEST​​​​​​​)
- python计算AUC、Accuracy、Recall、Precision和PPV
- 软件测试之测试用例设计(三)
- C语言3067答案,教师招聘《小学教育心理学》通关试题每日练(2020年03月03日-3067)...
- [统计学理论基础] 方差 协方差 标准差
- 再生核希尔伯特空间(RKHS)
- Element Ui之利用sort-change事件及sortable属性实现Table表格指定列的排序
- tvos 刷新焦点_如何为大型团队设置可扩展的iOS / tvOS / watchOS Xcode项目,并避免代码冲突?...