performance data helper库函数可以说是非常强大
如何获取计数器的路径呢,msdn讲述的规则可以说是非常的麻烦
当然,msdn也告诉我们可以使用 PdhBrowseCounters 函数来选择计数器,其实系统本身也有现成的程序给我们提供计数器路径
首先运行perfmon.msc
打开之后是这样的
然后在如图所示菜单弹出的地方右键
点击”添加计数器”
弹出一个对话框
这是我自己创建的一个叫做”jeff”的作业对象
点击添加,列表框中出现了一个计数器对象
但是必须要有全路径,当然是可以获取的
在列表框中右击
点击”属性”
高亮显示的地方就是作业对象的计数器的路径了
现发上测试代码:
#define _WIN32_WINNT 0x0500
#include
#include
#include
#pragma comment(lib,"Kernel32.lib")
#pragma comment(lib,"pdh.lib")
using namespace std;
void SetJobObject(HANDLE hObj);
void ShowJobInformation(HANDLE hObj);
bool QueryJobCountersByPDH(TCHAR* JobName,TCHAR* JobCountPath);
int main()
{
int err;
bool suc;
HANDLE hObj=CreateJobObject(NULL,TEXT("jeff"));
if(NULL==hObj)
{
cout<<"创建作业对象失败"<return 1;
}
SetJobObject(hObj);
STARTUPINFO si={sizeof(si)};
PROCESS_INFORMATION pi_spy={0};
PROCESS_INFORMATION pi_notepad={0};
TCHAR szPath[MAX_PATH]=TEXT("D:/vs2005/Common7/Tools/spyxx.exe");
TCHAR Notepath[MAX_PATH]=TEXT("notepad");
CreateProcess(NULL,szPath,NULL,NULL,false,CREATE_SUSPENDED,NULL,NULL,&si,&pi_spy);
CreateProcess(NULL,Notepath,NULL,NULL,false,CREATE_SUSPENDED,NULL,NULL,&si,&pi_notepad);
AssignProcessToJobObject(hObj,pi_notepad.hProcess);
SetJobObject(hObj);
AssignProcessToJobObject(hObj,pi_spy.hProcess);
ResumeThread(pi_spy.hThread);
ResumeThread(pi_notepad.hThread);
CloseHandle(pi_spy.hThread);
CloseHandle(pi_notepad.hThread);
HANDLE h[3];
h[0]=pi_spy.hProcess;
h[1]=pi_notepad.hProcess;
h[2]=hObj;
//ShowPDHDialog();
TCHAR CounterPath[MAX_PATH]=TEXT("\\Job Object(jeff)\\Current % Processor Time");
suc=QueryJobCountersByPDH(TEXT("jeff"),CounterPath);
if(!suc)
{
cout<<"获取jeff作业信息失败"<return 2;
}
DWORD dw=WaitForMultipleObjects(3,h,false,INFINITE);
switch(dw-WAIT_OBJECT_0)
{
case 0:
cout<<"spy结束"<break;
case 1:
cout<<"notepad结束"<break;
case 2:
cout<<"作业结束"<break;
}
ShowJobInformation(hObj);
CloseHandle(pi_spy.hProcess);
CloseHandle(pi_notepad.hProcess);
CloseHandle(hObj);
system("pause");
return 0;
}
void SetJobObject(HANDLE hObj)
{
if(hObj==NULL)
{
cout<<"传入的作业句柄为空"<return;
}
JOBOBJECT_BASIC_LIMIT_INFORMATION job1={0};
job1.PerJobUserTimeLimit.QuadPart=10000000;
job1.PriorityClass=IDLE_PRIORITY_CLASS;
job1.MinimumWorkingSetSize=1;
job1.MaximumWorkingSetSize=10;
job1.ActiveProcessLimit=5;
job1.LimitFlags=JOB_OBJECT_LIMIT_PRIORITY_CLASS|JOB_OBJECT_LIMIT_JOB_TIME|JOB_OBJECT_LIMIT_WORKINGSET|JOB_OBJECT_LIMIT_ACTIVE_PROCESS;
bool suc=SetInformationJobObject(hObj,JobObjectBasicLimitInformation,&job1,sizeof(job1));
if(suc)
{
cout<<"设置成功"<0};
job2.UIRestrictionsClass=JOB_OBJECT_UILIMIT_EXITWINDOWS|JOB_OBJECT_UILIMIT_HANDLES;
suc=SetInformationJobObject(hObj,JobObjectBasicUIRestrictions,&job2,sizeof(JOBOBJECT_BASIC_UI_RESTRICTIONS));
if(suc)
{
cout<<"设置成功"<void ShowJobInformation(HANDLE hObj)
{
if(hObj==NULL)
{
cout<<"传入的作业句柄为空"<return;
}
JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION job={0};
DWORD length;
bool ret=QueryInformationJobObject(hObj,JobObjectBasicAndIoAccountingInformation,&job,sizeof(job),&length);
if(!ret)
{
cout<<"获取作业信息失败"<return;
}
cout<<"job.BasicInfo.TotalUserTime:"<cout<<"job.BasicInfo.TotalKernelTime:"<cout<<"job.BasicInfo.ThisPeriodTotalUserTime:"<cout<<"job.BasicInfo.ThisPeriodTotalKernelTime:"<cout<<"job.BasicInfo.TotalPageFaultCount:"<cout<<"job.BasicInfo.TotalTerminatedProcesses:"<cout<<"job.BasicInfo.ActiveProcesses:"<cout<<"job.BasicInfo.TotalProcesses:"<cout<<"job.IoInfo.OtherOperationCount:"<cout<<"job.IoInfo.OtherTransferCount:"<cout<<"job.IoInfo.ReadOperationCount:"<cout<<"job.IoInfo.ReadTransferCount:"<cout<<"job.IoInfo.WriteOperationCount:"<cout<<"job.IoInfo.WriteTransferCount:"<bool QueryJobCountersByPDH(TCHAR* JobName,TCHAR* JobCountPath)
{
PDH_HQUERY hQuery;
PDH_STATUS status;
//创建一个查询对象
status=PdhOpenQuery(NULL,NULL,&hQuery);
if(ERROR_SUCCESS!=status)
{
return false;
}
//添加计数器(句柄其实是个指针)
HCOUNTER counter;
counter=(HCOUNTER*)GlobalAlloc(GPTR,sizeof(HCOUNTER));
status=PdhAddCounter(hQuery,JobCountPath,NULL,&counter);
if(ERROR_SUCCESS!=status)
{
return false;
}
//收集性能数据
status=PdhCollectQueryData(hQuery);
if(ERROR_SUCCESS!=status)
{
return false;
}
Sleep(1000);
status=PdhCollectQueryData(hQuery);
if(ERROR_SUCCESS!=status)
{
return false;
}
Sleep(1000);
status=PdhCollectQueryData(hQuery);
if(ERROR_SUCCESS!=status)
{
return false;
}
//显示性能数据
DWORD countertype;
PDH_FMT_COUNTERVALUE countervalue;
status=PdhGetFormattedCounterValue(counter,PDH_FMT_LARGE,&countertype,&countervalue);
if(ERROR_SUCCESS!=status)
{
return false;
}
cout<//关闭查询
PdhCloseQuery(hQuery);
return true;
}
实测计数器路径有本机名的情况下,程序会发生无法预测的问题,去掉主机名程序顺利完成
“\Job Object(jeff)\Current % Processor Time”去掉前面的主机名
测试结果