计算CPU的方法

来源:互联网 发布:淘宝上买药提交需求 编辑:程序博客网 时间:2024/05/02 04:16
//.h#ifndef _CPUUSAGE_H #define _CPUUSAGE_H #include <windows.h> #include <WINPERF.H> #include <comdef.h> // for using bstr_t class #include <atlbase.h>#include "stdafx.h"     #pragma pack(push,8)     #pragma pack(pop)    #define SYSTEM_OBJECT_INDEX                 2       // 'System' object    #define PROCESS_OBJECT_INDEX                230     // 'Process' object    #define PROCESSOR_OBJECT_INDEX              238     // 'Processor' object    #define TOTAL_PROCESSOR_TIME_COUNTER_INDEX  240     // '% Total processor time' counter (valid in WinNT under 'System' object)    #define PROCESSOR_TIME_COUNTER_INDEX        6       // '% processor time' counter (for Win2K/XP)    #define TOTALBYTES    100*1024 #define BYTEINCREMENT 10*1024   class CCpuUsage { public:  CCpuUsage();  virtual ~CCpuUsage();  // Methods  int GetCpuUsage();  int GetCpuUsage(LPCTSTR pProcessName);   BOOL EnablePerformaceCounters(BOOL bEnable = TRUE);  // Attributes private:  bool   m_bFirstTime;  LONGLONG  m_lnOldValue ;  LARGE_INTEGER m_OldPerfTime100nSec; };    template <class T> class CPerfCounters { public:  CPerfCounters()  {  }  ~CPerfCounters()  {  }   T GetCounterValue(PERF_DATA_BLOCK **pPerfData, DWORD dwObjectIndex, DWORD dwCounterIndex, LPCTSTR pInstanceName = NULL)  {   QueryPerformanceData(pPerfData, dwObjectIndex, dwCounterIndex);       PPERF_OBJECT_TYPE pPerfObj = NULL;   T lnValue = {0};    // Get the first object type.   pPerfObj = FirstObject( *pPerfData );    // Look for the given object index    for( DWORD i=0; i<(*pPerfData)->NumObjectTypes; i++ )   {     if (pPerfObj->ObjectNameTitleIndex == dwObjectIndex)    {     lnValue = GetCounterValue(pPerfObj, dwCounterIndex, pInstanceName);     break;    }     pPerfObj = NextObject( pPerfObj );   }   return lnValue;  }  protected:   class CBuffer  {  public:   CBuffer(UINT Size)   {    m_Size = Size;    m_pBuffer = (LPBYTE) malloc( Size*sizeof(BYTE) );   }   ~CBuffer()   {    free(m_pBuffer);   }   void *Realloc(UINT Size)   {    m_Size = Size;    m_pBuffer = (LPBYTE) realloc( m_pBuffer, Size );    return m_pBuffer;   }    void Reset()   {    memset(m_pBuffer,NULL,m_Size);   }   operator LPBYTE ()   {    return m_pBuffer;   }    UINT GetSize()   {    return m_Size;   }  public:   LPBYTE m_pBuffer;  private:   UINT m_Size;  };   //  // The performance data is accessed through the registry key   // HKEY_PEFORMANCE_DATA.  // However, although we use the registry to collect performance data,   // the data is not stored in the registry database.  // Instead, calling the registry functions with the HKEY_PEFORMANCE_DATA key   // causes the system to collect the data from the appropriate system   // object managers.  //  // QueryPerformanceData allocates memory block for getting the  // performance data.  //  //  void QueryPerformanceData(PERF_DATA_BLOCK **pPerfData, DWORD dwObjectIndex, DWORD dwCounterIndex)  {   //   // Since i want to use the same allocated area for each query,   // i declare CBuffer as static.   // The allocated is changed only when RegQueryValueEx return ERROR_MORE_DATA   //   static CBuffer Buffer(TOTALBYTES);    DWORD BufferSize = Buffer.GetSize();   LONG lRes;    char keyName[8];   sprintf(keyName,"%d %d",dwObjectIndex, dwCounterIndex);    Buffer.Reset();   while( (lRes = RegQueryValueEx( HKEY_PERFORMANCE_DATA,            keyName,            NULL,            NULL,            Buffer,            &BufferSize )) == ERROR_MORE_DATA )   {    // Get a buffer that is big enough.     BufferSize += BYTEINCREMENT;    Buffer.Realloc(BufferSize);   }   *pPerfData = (PPERF_DATA_BLOCK) Buffer.m_pBuffer;  }   //  // GetCounterValue gets performance object structure  // and returns the value of given counter index .  // This functions iterates through the counters of the input object  // structure and looks for the given counter index.  //  // For objects that have instances, this function returns the counter value  // of the instance pInstanceName.  //  T GetCounterValue(PPERF_OBJECT_TYPE pPerfObj, DWORD dwCounterIndex, LPCTSTR pInstanceName)  {   PPERF_COUNTER_DEFINITION pPerfCntr = NULL;   PPERF_INSTANCE_DEFINITION pPerfInst = NULL;   PPERF_COUNTER_BLOCK pCounterBlock = NULL;    // Get the first counter.    pPerfCntr = FirstCounter( pPerfObj );    // Look for the index of '% Total processor time'    for( DWORD j=0; j < pPerfObj->NumCounters; j++ )   {    if (pPerfCntr->CounterNameTitleIndex == dwCounterIndex)     break;     // Get the next counter.     pPerfCntr = NextCounter( pPerfCntr );   }    if( pPerfObj->NumInstances == PERF_NO_INSTANCES )     {    pCounterBlock = (PPERF_COUNTER_BLOCK) ((LPBYTE) pPerfObj + pPerfObj->DefinitionLength);   }   else   {    pPerfInst = FirstInstance( pPerfObj );       // Look for instance pInstanceName    _bstr_t bstrInstance;    _bstr_t bstrInputInstance = pInstanceName;    for( int k=0; k< pPerfObj->NumInstances; k++ )    {     bstrInstance = (wchar_t *)((PBYTE)pPerfInst + pPerfInst->NameOffset);     if (!stricmp((LPCTSTR)bstrInstance, (LPCTSTR)bstrInputInstance))     {      pCounterBlock = (PPERF_COUNTER_BLOCK) ((LPBYTE) pPerfInst + pPerfInst->ByteLength);      break;     }          // Get the next instance.      pPerfInst = NextInstance( pPerfInst );    }   }    if (pCounterBlock)   {    T *lnValue = NULL;    lnValue = (T*)((LPBYTE) pCounterBlock + pPerfCntr->CounterOffset);    return *lnValue;   }   return -1;  }    /*****************************************************************   *                                                               *   * Functions used to navigate through the performance data.      *   *                                                               *   *****************************************************************/   PPERF_OBJECT_TYPE FirstObject( PPERF_DATA_BLOCK PerfData )  {   return( (PPERF_OBJECT_TYPE)((PBYTE)PerfData + PerfData->HeaderLength) );  }   PPERF_OBJECT_TYPE NextObject( PPERF_OBJECT_TYPE PerfObj )  {   return( (PPERF_OBJECT_TYPE)((PBYTE)PerfObj + PerfObj->TotalByteLength) );  }   PPERF_COUNTER_DEFINITION FirstCounter( PPERF_OBJECT_TYPE PerfObj )  {   return( (PPERF_COUNTER_DEFINITION) ((PBYTE)PerfObj + PerfObj->HeaderLength) );  }   PPERF_COUNTER_DEFINITION NextCounter( PPERF_COUNTER_DEFINITION PerfCntr )  {   return( (PPERF_COUNTER_DEFINITION)((PBYTE)PerfCntr + PerfCntr->ByteLength) );  }   PPERF_INSTANCE_DEFINITION FirstInstance( PPERF_OBJECT_TYPE PerfObj )  {   return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfObj + PerfObj->DefinitionLength) );  }   PPERF_INSTANCE_DEFINITION NextInstance( PPERF_INSTANCE_DEFINITION PerfInst )  {   PPERF_COUNTER_BLOCK PerfCntrBlk;    PerfCntrBlk = (PPERF_COUNTER_BLOCK)((PBYTE)PerfInst + PerfInst->ByteLength);    return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfCntrBlk + PerfCntrBlk->ByteLength) );  } };#endif//.cpp///////////////////////////////////////////////////////////////////    //    //      GetCpuUsage uses the performance counters to retrieve the    //      system cpu usage.    //      The cpu usage counter is of type PERF_100NSEC_TIMER_INV    //      which as the following calculation:    //    //      Element     Value     //      =======     ===========    //      X           CounterData     //      Y           100NsTime     //      Data Size   8 Bytes    //      Time base   100Ns    //      Calculation 100*(1-(X1-X0)/(Y1-Y0))     //    //      where the denominator (Y) represents the total elapsed time of the     //      sample interval and the numerator (X) represents the time during     //      the interval when the monitored components were inactive.    //    //    //      Note:    //      ====    //      On windows NT, cpu usage counter is '% Total processor time'    //      under 'System' object. However, in Win2K/XP Microsoft moved    //      that counter to '% processor time' under '_Total' instance    //      of 'Processor' object.    //      Read 'INFO: Percent Total Performance Counter Changes on Windows 2000'    //      Q259390 in MSDN.    //    ///////////////////////////////////////////////////////////////////    #include "stdafx.h"#include "cpu.h"typedef enum   {    WINNT,  WIN2K_XP, WIN9X, UNKNOWN   }PLATFORM;   PLATFORM GetPlatform()   {    OSVERSIONINFO osvi;    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);    if (!GetVersionEx(&osvi))     return UNKNOWN;    switch (osvi.dwPlatformId)    {    case VER_PLATFORM_WIN32_WINDOWS:     return WIN9X;    case VER_PLATFORM_WIN32_NT:     if (osvi.dwMajorVersion == 4)      return WINNT;     else      return WIN2K_XP;    }    return UNKNOWN;   }   CCpuUsage::CCpuUsage()   {    m_bFirstTime = true;    m_lnOldValue = 0;    memset(&m_OldPerfTime100nSec, 0, sizeof(m_OldPerfTime100nSec));   }   CCpuUsage::~CCpuUsage()   {   }   BOOL CCpuUsage::EnablePerformaceCounters(BOOL bEnable)   {    if (GetPlatform() != WIN2K_XP)     return TRUE;    CRegKey regKey;    if (regKey.Open(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\PerfOS\\Performance") != ERROR_SUCCESS)     return FALSE;    regKey.SetValue(!bEnable, "Disable Performance Counters");    regKey.Close();    if (regKey.Open(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\PerfProc\\Performance") != ERROR_SUCCESS)     return FALSE;    regKey.SetValue(!bEnable, "Disable Performance Counters");    regKey.Close();    return TRUE;   }   //    //  GetCpuUsage returns the system-wide cpu usage.    //  Since we calculate the cpu usage by two samplings, the first    //  call to GetCpuUsage() returns 0 and keeps the values for the next    //  sampling.    //  Read the comment at the beginning of this file for the formula.    //    int CCpuUsage::GetCpuUsage()   {    static PLATFORM Platform = GetPlatform();    if (m_bFirstTime)     EnablePerformaceCounters();    // Cpu usage counter is 8 byte length.     CPerfCounters<LONGLONG> PerfCounters;    char szInstance[256] = {0};    //      Note:     //      ====     //      On windows NT, cpu usage counter is '% Total processor time'     //      under 'System' object. However, in Win2K/XP Microsoft moved     //      that counter to '% processor time' under '_Total' instance     //      of 'Processor' object.     //      Read 'INFO: Percent Total Performance Counter Changes on Windows 2000'     //      Q259390 in MSDN.     DWORD dwObjectIndex;    DWORD dwCpuUsageIndex;    switch (Platform)    {    case WINNT:     dwObjectIndex = SYSTEM_OBJECT_INDEX;     dwCpuUsageIndex = TOTAL_PROCESSOR_TIME_COUNTER_INDEX;     break;    case WIN2K_XP:     dwObjectIndex = PROCESSOR_OBJECT_INDEX;     dwCpuUsageIndex = PROCESSOR_TIME_COUNTER_INDEX;     strcpy(szInstance,"_Total");     break;    default:     return -1;    }    int             CpuUsage = 0;    LONGLONG        lnNewValue = 0;    PPERF_DATA_BLOCK pPerfData = NULL;    LARGE_INTEGER   NewPerfTime100nSec = {0};    lnNewValue = PerfCounters.GetCounterValue(&pPerfData, dwObjectIndex, dwCpuUsageIndex, szInstance);    NewPerfTime100nSec = pPerfData->PerfTime100nSec;    if (m_bFirstTime)    {     m_bFirstTime = false;     m_lnOldValue = lnNewValue;     m_OldPerfTime100nSec = NewPerfTime100nSec;     return 0;    }    LONGLONG lnValueDelta = lnNewValue - m_lnOldValue;    double DeltaPerfTime100nSec = (double)NewPerfTime100nSec.QuadPart - (double)m_OldPerfTime100nSec.QuadPart;    m_lnOldValue = lnNewValue;    m_OldPerfTime100nSec = NewPerfTime100nSec;    double a = (double)lnValueDelta / DeltaPerfTime100nSec;    double f = (1.0 - a) * 100.0;    CpuUsage = (int)(f + 0.5);  // rounding the result     if (CpuUsage == 0)     return 0;    return CpuUsage;   }   int CCpuUsage::GetCpuUsage(LPCTSTR pProcessName)   {    static PLATFORM Platform = GetPlatform();    if (m_bFirstTime)     EnablePerformaceCounters();    // Cpu usage counter is 8 byte length.     CPerfCounters<LONGLONG> PerfCounters;    char szInstance[256] = {0};    DWORD dwObjectIndex = PROCESS_OBJECT_INDEX;    DWORD dwCpuUsageIndex = PROCESSOR_TIME_COUNTER_INDEX;    strcpy(szInstance,pProcessName);    int             CpuUsage = 0;    LONGLONG        lnNewValue = 0;    PPERF_DATA_BLOCK pPerfData = NULL;    LARGE_INTEGER   NewPerfTime100nSec = {0};    lnNewValue = PerfCounters.GetCounterValue(&pPerfData, dwObjectIndex, dwCpuUsageIndex, szInstance);    NewPerfTime100nSec = pPerfData->PerfTime100nSec;    if (m_bFirstTime)    {     m_bFirstTime = false;     m_lnOldValue = lnNewValue;     m_OldPerfTime100nSec = NewPerfTime100nSec;     return 0;    }    LONGLONG lnValueDelta = lnNewValue - m_lnOldValue;    double DeltaPerfTime100nSec = (double)NewPerfTime100nSec.QuadPart - (double)m_OldPerfTime100nSec.QuadPart;    m_lnOldValue = lnNewValue;    m_OldPerfTime100nSec = NewPerfTime100nSec;    double a = (double)lnValueDelta / DeltaPerfTime100nSec;    CpuUsage = (int) (a*100);    if (CpuUsage == 0)     return 0;    return CpuUsage;   }   

原创粉丝点击