用Pdh库获得CPU利用率 cpu利用率怎么算

花了三天时间搞清楚了Pdh库中几个函数的具体用法,MSDN上只有解释,没有示例;网上查资料,也没能帮我解决问题,可能由于硬件和操作系统不同,网上提供的代码在我机器上不能运行,具体是哪的错误网上没有查到相关资料。无计可施的时候,一次无聊的尝试,成功了,然后顿悟。现整理如下:

可以用Pdh(performance datahelper)库提供的一些函数来获取系统当前的一些性能数据(也可以读取日志文件获取之前的一些性能数据)。下面以以cpu的利用率为例介绍。

头文件: Pdh.h(用#include<Pdh.h>包含)

静态链接库: Pdh.lib (可以用宏语句 #pragmacomment(lib,"Pdh.lib")来加载)

动态连接库: Pdh.dll(可以在主函数内用语句 HMODULEhModule=LoadLibraryEx("Pdh.dll",NULL,LOAD_LIBRARY_AS_DATAFILE)来加载动态连接库,用FreeLibrary(hModule)语句来释放动态连接库)

用Pdh库获得当前CPU利用率的步骤如下:

1、打开查询(query)句柄。

HQUERYhquery; //声明查询句柄hquery

PDHSTATUSpdhstatus=PdhOpenQuery(0,0,&hquery);

2、在查询中加入计数器(counter)(一个query中可以加入好几个counter,本例中之加入了一个counter)

HCOUNTER*pdhcounter; //计数器句柄的指针

pdhcounter=(HCOUNTER*)GlobalAlloc(GPTR,(sizeof(HCOUNTER)));//为计数器分配存储空间

PdhAddCounter(hquery,"\ProcessorInformation(_Total)\% ProcessorTime",0,pdhcounter);//向查询hquery中加入计数器pdhcounter,函数的第二个参数是指定要加入什么样的技术器(就是在这里指定“cpu利用率”计数器),其格式是\ComputerPerfObject(parent_instance/instance#index)counter,其中,Computer指定要检测哪台计算机的性能,可以用ip地址指定网络中一台其他的计算机,本机时可以省略;PerfObject指定性能对象,即对哪类对象(可以是处理器(ProcessorInformation),在其他系统中可能还可以是进程Process)进行检查,instance指定这类对象中的一个实例(如多个cpu时指定是哪个cpu(或者他们的和Total),对象是Process是可以指定是哪个进程等等),parent_instance和#index(index是数字,表示第几个instance)都是在只用instance无法识别是哪个进程时,需要加入的项(instance独一无二时,他们可以省略),counter指定前面指定的对象上的某个计数器(如ProcessorInformation对象上有% Processor Time计数器,% Processor Time是一个整体,%是计数器名字的一部分,要谨记的是%和P之间有一个空格,少写这个空格将找不到计数器)

用GlobalAlloc()为pdhcounter分配的存储空间,当pdhcounter不再使用的时候,要用GlobalFree(pdhcounter)函数将其释放。

3、收集query的数据(query中的所有counter的数据都会被收集)

PdhCollectQueryData(hquery);//特别需要注意的是,用些counter数据(如rate、% ProcessorTime)需要Collect两次才能得到,有人遇到获取的cpu利用率总是0这个问题,那是因为虽然你用了两个PdhCollectQueryData()两次(否则会出错),但这两条相同的语句是紧挨着的,Pdh函数会计算这两个PdhCollectQueryData()之间这段时间的cpu利用率,所以将如两条语句紧挨着,那么这个间隔时间太短,所以得到的数据不太理想,解决办法是可以在两条PdhCollectQueryData()语句之间加入一条Sleep(50)语句,这样就可以得到50毫秒这段时间间隔内的cpu利用率,当然也可以加入一些其他的语句。

4、获得格式化(可以显示的)数据

PdhCollectQueryDat a(hquery)函数获得的数据是原始数据(rawdata),可以用如下方法获得可显示的数据

PDH_FMT_COUNTERVALUEpdh_counter_value;

DWORDpdh_counter_value_type;

PdhGetFormattedCounterValu(*pdhcounter,PDH_FMT_DOUBLE,&pdh_counter_value_type,&pdh_counter_value);

pdh_counter_value.doublevalue中存的就是要得到的double值(当然,也可以获得LONG等其他类型的值)。

5、从query中删除不用的counter(一个query中可以加入好几个counter,本例中其实只加入了一个counter)

PdhRemoveCounter(*pdhcounter);//注意,不用指定是哪个query,因为counter信息中包含自己属于哪个query

6、关闭query(这会关闭query并且释放其中所有的counter及所占用的存储空间)

PdhCloseQuery(hquery);

注1:以上某个步骤中的语句不是写程序中的精确顺序,只是从逻辑上写出了他们的顺序

注2:以上介绍的函数,都没有说个参数的具体含义,这些可以从MSDN官网上查,都有的

以下c++程序可以作为参考,在双核环境下获得某个cpu核的利用率:

#include<stdio.h>
#include<windows.h>
#include<Pdh.h>
#include<iostream>
#include<PDHMsg.h>

#pragma comment(lib, "Pdh.lib")
using namespace std;

void display_error(HMODULE hModule,DWORDpdhstatu) //输出显示错误信息
{
//HMODULE hModule;
int error_count;
LPVOID p_error_message;
//hModule=LoadLibraryEx("Pdh.dll",NULL,LOAD_LIBRARY_AS_DATAFILE);
if(hModule==NULL)
{
printf("hmodule is NULLn");
return;
}
error_count=FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_FROM_HMODULE|FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_IGNORE_INSERTS,hModule,pdhstatu,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR)&p_error_message,0,NULL);
printf("%s",p_error_message);
LocalFree(p_error_message);
//FreeLibrary(hModule);
}
int main()
{
HMODULE hModule1;
HQUERY hquery=NULL;
PDH_STATUS pdhstatus;
HCOUNTER* pcounterhandle=NULL;
PDH_FMT_COUNTERVALUE fmtcountervalue;
DWORD pcountervaluetype;


hModule1=LoadLibraryEx("Pdh.dll",NULL,LOAD_LIBRARY_AS_DATAFILE);
if(hModule1==NULL)
{
printf("hmodule is NULLn");
}


SetProcessAffinityMask(GetCurrentProcess(),0x00000001);//把当前进程设置在某一个cpu上执行
__try
{
pdhstatus=PdhOpenQuery(0,0,&hquery);
if(pdhstatus!=ERROR_SUCCESS)
{
printf("open queryerrorn");
display_error(hModule1,pdhstatus);
__leave;
}
if(hquery==NULL)
{
printf("11n");
}
pcounterhandle=(HCOUNTER*)GlobalAlloc(GPTR,sizeof(HCOUNTER));
}
__finally
用Pdh库获得CPU利用率 cpu利用率怎么算
{
if(AbnormalTermination())
{
printf("The try block of the terminate handle endabnormallyn");
}
}


__try
{
pdhstatus=PdhAddCounter(hquery,"\ProcessorInformation(0,0)\% Processor Time",0,pcounterhandle);
if(pdhstatus!=ERROR_SUCCESS)
{
printf("addcountererrn");
display_error(hModule1,pdhstatus);
__leave;
}

pdhstatus=PdhCollectQueryData(hquery);

Sleep(50);

pdhstatus=PdhCollectQueryData(hquery);
if(pdhstatus!=ERROR_SUCCESS)
{
printf("collect query errn");
display_error(hModule1,pdhstatus);
__leave;
}


pdhstatus=PdhGetFormattedCounterValue(*pcounterhandle,PDH_FMT_DOUBLE,&pcountervaluetype,&fmtcountervalue);
if(pdhstatus!=ERROR_SUCCESS)
{
printf("getformat data errorn");
display_error(hModule1,pdhstatus);
__leave;
}
}
__finally
{
if(AbnormalTermination())
{
printf("Thetry block of termination handle terminate abnormal.n");
}
}

pdhstatus=PdhRemoveCounter(*pcounterhandle);
if(pdhstatus!=ERROR_SUCCESS)
{
printf("remove counter errorn");
display_error(hModule1,pdhstatus);
}

pdhstatus=PdhCloseQuery(hquery);
if(pdhstatus!=ERROR_SUCCESS)
{
printf("closeabnormallyn");
display_error(hModule1,pdhstatus);
}

FreeLibrary(hModule1);
return 0;
}

  

爱华网本文地址 » http://www.aihuau.com/a/25101016/319747.html

更多阅读

怎样识别笔记本CPU型号 笔记本cpu型号怎么看

怎样识别笔记本CPU型号——简介小白买笔记本容易被奸商狠宰,而 CPU 往往是最好下手的地方。那么,对于市场上琳琅满目的 CPU,要怎样才能识别它们的好坏呢?怎样识别笔记本CPU型号——方法/步骤怎样识别笔记本CPU型号 1、现在市场上的笔记

怎么获得qt兑换券 tgp兑换券怎么获得

怎么获得qt兑换券——简介怎么获得qt兑换券 怎么获得qt兑换券——方法/步骤怎么获得qt兑换券 1、在LOL游戏中不管玩家在哪个房间里面玩都会得到积分,但是每个玩家一天最多获得5个个人积分。怎么获得qt兑换券 2、玩家中会员的积分会

QT贡献、积分以及QT兑换券的获得怎么算 qt语音兑换券

QT贡献、积分以及QT兑换券的获得怎么算——简介QT是腾讯公司出品的一款语音聊天软件。下面我介绍一下QT的贡献以及积分如何计算,以及涉及到QT兑换券的获得的计算方式。QT贡献、积分以及QT兑换券的获得怎么算——工具/原料1.首先下载

怎么用眼线膏画眼线? 眼线膏怎么画内眼线

怎么用眼线膏画眼线?——简介眼线并不是一成不变的,不同的眼睛适合不同的眼线画法。怎么用眼线膏画眼线?——方法/步骤怎么用眼线膏画眼线? 1、学学眼线膏画法怎么用眼线膏画眼线? 2、用眼线刷取一点眼线膏,在手背上涂抹均匀,并调整刷毛

声明:《用Pdh库获得CPU利用率 cpu利用率怎么算》为网友有些过客分享!如侵犯到您的合法权益请联系我们删除