windows 性能计数器

来源:互联网 发布:mac os升级 编辑:程序博客网 时间:2024/04/28 03:40
一、性能计数器概述
  性能监视,是Windows NT提供的一种系统功能。Windows NT一直以来总是集成了性能监视工具,它提供有关操作系统当前运行状况的信息,针对各种对象提供了数百个性能计数器。性能对象,就是被监视的对象,典型例子有Processor、Process、Memory、TCP/UDP/IP/ICMP、PhysicalDisk等。计数器通常提供操作系统、应用程序、服务、驱动程序等的性能相关信息,以此来分析系统瓶颈和对系统及应用程序性能进行诊断和调优。性能计数器机制让应用程序和操作系统组件可以向性能监视应用程序,比如性能监视器(Performance Monitor),报告一些与性能有关的统计信息。PerfMon.exe中可以查看性能对象、性能计数器和对象实例,可通过添加计数器来查看相关描述信息。

  实际上,可以通过编写程序来访问所有的Windows性能计数器。Windows中,注册表是访问性能计数器的一种机制。性能信息并不实际存在于注册表中,在注册表编辑器RegEdit.exe中是无法查看的,但可以通过注册表函数来访问,利用注册表键来获得从性能数据提供者那里提供的数据。打开名为HKEY_PERFORMANCE_DATA的特殊键,利用RegQueryValueEx函数查询键下面的值,就可以直接访问注册表性能计数器信息。当然,也可以利用性能数据帮助器(PDH, Performance Data Helper) API (Pdh.dll)来访问性能计数器信息。

二、相关术语
性能对象(Performance Object):被监视的性能对象,如Processor、Process、Memory、PhysicalDisk等,相当于类(Class)。
性能计数器(Performance Counter):描述性能对象性能信息的方式,相当于类属性。
对象实例(Object Instance):相同性能对象可能有多个,把它们表示为该对象类型的不同实例,相当于类实例。

三、HKEY_PERFORMANCE_DATA数据组织
  性能数据的头部是一个PERF_DATA_BLOCK结构(如图1所示),它描述系统和性能数据总体信息,可从Global键值处查询得到该结构数据。PERF_DATA_BLOCK之后,定义了系统中的全部性能对象类型(PERF_OBJECT_TYPE),其中每个对象类型头部中描述了下一个性能对象类型的偏移量Offset。
图1  图1图2图2


  性能对象有两种:一种是单实例对象,另一种是多实例对象。图2和图3分别描述了这两种性能对象的数据组织方式。每个对象数据块包含了一个PERF_OBJECT_TYPE结构,描述对象的性能数据。紧随其后是PERF_COUNTER_DEFINITION结构列表,描述了性能对象的全部计数器定义。对于单实例对象,计数器定义列表后是一个PERF_COUNTER_BLOCK结构,计数器数据紧随其后。每个PERF_COUNTER_DEFINITION结构中定义了计数器数据相对于PERF_COUNTER_BLOCK的偏移量,因此可以非常方便地获得全部计数器的值。对支持多实例性能对象来说,PERF_COUNTER_DEFINITION结构列表之后是一组实例信息数据块,每个表示代表一个对象实例。每个实例信息数据块由一个PERF_INSTANCE_DEFINITION结构体、实例名和一个PERF_COUNTER_BLOCK结构体组成。后面是计数器值数据,与单实例对象相同。

图3图3

四、一个简单性能计数器查看器的实现
  基于以上的知识和一些参考文献,本人在Windows Xp Sp3 + VS2003环境下实现了一个Windows性能计数器查看器。界面如图4所示,核心部分代码如下:

图4

1、头文件winperf.h

 

view plaincopy to clipboardprint?
  1. #ifndef _WINPERF   
  2. #define _WINPERF   
  3.   
  4. #include "stdafx.h"   
  5. #include <windows.h>   
  6. #include <tchar.h>          
  7. #include <io.h>   
  8. #include <conio.h>   
  9. #include <string.h>   
  10. #include <stdio.h>   
  11. #include <strsafe.h>   
  12. #include <winperf.h>   
  13. #include <String>   
  14. #include <vector>   
  15. #include <map>   
  16. #include <iostream>   
  17. using namespace std;   
  18.   
  19. #define INITIAL_SIZE        51200  
  20. #define EXTEND_SIZE         25600  
  21. #define PERF_SUBKEY_GLOBAL  _T("Global")   
  22. #define REGSUBKEY_COUNTERS  _T("Counters")   
  23.   
  24. typedef map <DWORDDWORD>::const_iterator CIT;   
  25.   
  26. BOOL ConnectComputerPerformanceRegistry(LPCSTR lpMachineName, HKEY &hKey);   
  27. BOOL GetNameStrings(HKEY hKey, map <DWORDLPSTR&mPerfObjectIndex);   
  28. BOOL EnumPerfObjects(HKEY hKey, vector <PERF_OBJECT_TYPE> &vPerfObjects);   
  29. BOOL LoadObjectData(HKEY hKey, DWORD dwObjIndex, map <DWORDLPSTRmPerfCountersIndex, \   
  30.     CListBox *pCListBoxCounters, CListCtrl *pCListCtrlInstances);   
  31.   
  32. #endif  

2、连接(远程)计算机性能计数器注册表

 

 

view plaincopy to clipboardprint?
  1. BOOL ConnectComputerPerformanceRegistry(LPCSTR lpMachineName, HKEY &hKey)   
  2. {   
  3.     DWORD retCode;   
  4.   
  5.     retCode RegConnectRegistry(lpMachineName, HKEY_PERFORMANCE_DATA, &hKey);   
  6.     return (retCode == ERROR_SUCCESS) TRUE FALSE;   
  7.  

3、枚举性能对象


 


view plaincopy to clipboardprint?
  1. static inline PPERF_OBJECT_TYPE FirstObject(PPERF_DATA_BLOCK PerfData)      
  2.      
  3.     return((PPERF_OBJECT_TYPE)((PBYTE)PerfData PerfData->HeaderLength));      
  4.      
  5.   
  6. static inline PPERF_OBJECT_TYPE NextObject(PPERF_OBJECT_TYPE PerfObj)      
  7.      
  8.     return((PPERF_OBJECT_TYPE)((PBYTE)PerfObj PerfObj->TotalByteLength));      
  9. }   
  10.   
  11. BOOL EnumPerfObjects(HKEY hKey, vector <PERF_OBJECT_TYPE> &vPerfObjects)   
  12. {   
  13.     DWORD  retCode ERROR_MORE_DATA;   
  14.     DWORD  dwType 0;   
  15.     DWORD  dwSize 0;   
  16.     PPERF_DATA_BLOCK PerfData (PPERF_DATA_BLOCK)malloc(INITIAL_SIZE);   
  17.     PPERF_OBJECT_TYPE PPerfObj;   
  18.   
  19.     while (retCode == ERROR_MORE_DATA)   
  20.     {   
  21.         dwSize += EXTEND_SIZE;   
  22.         PerfData (PPERF_DATA_BLOCK)realloc(PerfData, dwSize);    
  23.         retCode RegQueryValueEx(hKey, PERF_SUBKEY_GLOBAL, 0, &dwType, (LPBYTE)PerfData, &dwSize);   
  24.     }   
  25.     if (retCode != ERROR_SUCCESS)   
  26.         return FALSE;   
  27.   
  28.     PPerfObj FirstObject(PerfData);   
  29.     for (int 0; PerfData->NumObjectTypes; i++)   
  30.     {   
  31.         PERF_OBJECT_TYPE PerfObj;   
  32.         memcpy(&PerfObj, PPerfObj, sizeof(PERF_OBJECT_TYPE));   
  33.         vPerfObjects.push_back(PerfObj);   
  34.         PPerfObj NextObject(PPerfObj);   
  35.     }   
  36.   
  37.     return TRUE;   
  38.  


 


4、获取性能计数器名字


 


view plaincopy to clipboardprint?
  1. BOOL GetNameStrings(HKEY hKey, map <DWORDLPSTR&mPerfObjectIndex)   
  2. {   
  3.     DWORD  retCode 0;   
  4.     DWORD  dwType 0;   
  5.     DWORD  dwSize 0;   
  6.     LPBYTE buffer NULL;   
  7.     LPSTR  p, p2;    
  8.     LPSTR  lpCurrentString;   
  9.     DWORD  dwCounter 0;   
  10.   
  11.     retCode RegQueryValueEx(hKey, REGSUBKEY_COUNTERS, NULL, &dwType, NULL, &dwSize);   
  12.     if (retCode != ERROR_SUCCESS)   
  13.     {   
  14.         perror("RegQueryValueEx REGSUBKEY_COUNTERS Size");   
  15.         return FALSE;   
  16.     }   
  17.   
  18.     buffer (LPBYTE)malloc(dwSize);   
  19.     memset(buffer, 0, dwSize);   
  20.     retCode RegQueryValueEx(hKey, REGSUBKEY_COUNTERS, NULL, &dwType, buffer, &dwSize);   
  21.     if (retCode != ERROR_SUCCESS)   
  22.     {   
  23.         perror("RegQueryValueEx REGSUBKEY_COUNTERS Content");   
  24.         return FALSE;   
  25.     }   
  26.   
  27.     (LPSTRbuffer;   
  28.     for(lpCurrentString p; *lpCurrentString; lpCurrentString  += (lstrlen(lpCurrentString) 1))      
  29.          
  30.         dwCounter atol(lpCurrentString);      
  31.         lpCurrentString += (lstrlen(lpCurrentString) 1);         
  32.         mPerfObjectIndex[dwCounter] (LPSTR)lpCurrentString;   
  33.     }   
  34.   
  35.     return TRUE;   
  36.  

0 0
原创粉丝点击