Windows 下获取多核CPU使用率
该方法使用于NT内核的windows系统,windows2000以后的版本都适用。NT下利用ntdll.dll中没有公开的API: NtQuerySystemInformation,文档参考:http://msdn.microsoft.com/en-us/library/ms724509.aspx 扩展参考参考:MSDN 讲解如何利用NT Native API获取NT系统的CPU使用率(支持多核) Win32 SDK 获得多核心处理器使用率。 阅读更多查看代码 代码一: 产生CPU曲线,源自《编程之美》第一章 #include <windows.h> #include <stdlib.h> #include <math.h> const int SAMPLING_COUNT = 200; const double PI = 3.1415926535; const int TOTAL_AMPLITUDE = 600; int main(int argc, char* argv[]) { DWORD busySpan[SAMPLING_COUNT]; int amplitude = TOTAL_AMPLITUDE / 2; double radian = 0.0; double radianIncrement = 2.0 / (double) SAMPLING_COUNT; for (int i = 0; i< SAMPLING_COUNT; i++) { busySpan[i] = (DWORD) (amplitude + (sin(PI * radian) * amplitude)); radian += radianIncrement; } DWORD startTime = 0; for (int j = 0;; j = (j+1) % SAMPLING_COUNT) { startTime = GetTickCount(); while ((GetTickCount() - startTime ) <= busySpan[j]) ; Sleep(TOTAL_AMPLITUDE - busySpan[j]); } return 0; } 代码二: 获取CPU使用率 #include <windows.h> #include <stdio.h> #define SystemBasicInformation 0 #define SystemPerformanceInformation 2 #define SystemTimeInformation 3 #define SystemProcessorPerformanceInformation 8 #define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart)) typedef struct { DWORD dwUnknown1; ULONG uKeMaximumIncrement; ULONG uPageSize; ULONG uMmNumberOfPhysicalPages; ULONG uMmLowestPhysicalPage; ULONG uMmHighestPhysicalPage; ULONG uAllocationGranularity; PVOID pLowestUserAddress; PVOID pMmHighestUserAddress; ULONG uKeActiveProcessors; BYTE bKeNumberProcessors; BYTE bUnknown2; WORD wUnknown3; } SYSTEM_BASIC_INFORMATION; typedef struct { LARGE_INTEGER liIdleTime; DWORD dwSpare[76]; } SYSTEM_PERFORMANCE_INFORMATION; typedef struct { LARGE_INTEGER liKeBootTime; LARGE_INTEGER liKeSystemTime; LARGE_INTEGER liExpTimeZoneBias; ULONG uCurrentTimeZoneId; DWORD dwReserved; } SYSTEM_TIME_INFORMATION; typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION { LARGE_INTEGER IdleTime; LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER DpcTime; LARGE_INTEGER InterruptTime; ULONG Reserved2; } SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; typedef struct _m_PROCESSORS_USE_TIME { double dbOldIdleTime; // save old total time double dbOldCurrentTime; double dbIdleTime; // save time after calc double dbCurrentTime; float fUse; }m_PROCESSORS_USE_TIME; m_PROCESSORS_USE_TIME * m_PUT; SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION * m_pSPPI = NULL; int m_iNumberProcessors; typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG); PROCNTQSI NtQuerySystemInformation; static LARGE_INTEGER liOldIdleTime = {0,0}; static LARGE_INTEGER liOldSystemTime = {0,0}; double dbIdleTime = 0; double dbSystemTime = 0; double alldbIdleTime = 0; void init() { } int GetCpuUsage() { SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo; SYSTEM_TIME_INFORMATION SysTimeInfo; SYSTEM_BASIC_INFORMATION SysBaseInfo; LONG status; NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(GetModuleHandle("ntdll"),"NtQuerySystemInformation"); // get number of processors in the system status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL); if (status != NO_ERROR) return -1; if (!NtQuerySystemInformation) return -1; // get number of processors in the system status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL); if (status != NO_ERROR) return -1; // get new system time status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0); if (status!=NO_ERROR) return -1; // get new CPU's idle time status =NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL); if (status != NO_ERROR) return -1; if ( m_iNumberProcessors != SysBaseInfo.bKeNumberProcessors) { //save m_iNumberProcessors = SysBaseInfo.bKeNumberProcessors; //if sppi not null clear if (m_pSPPI != NULL) delete []m_pSPPI; if (m_PUT != NULL) delete []m_PUT; //malloc and point m_pSPPI = new SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION[m_iNumberProcessors]; m_PUT = new m_PROCESSORS_USE_TIME[m_iNumberProcessors]; } // get ProcessorPer time status =NtQuerySystemInformation(SystemProcessorPerformanceInformation, m_pSPPI, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * m_iNumberProcessors, NULL); if (status != NO_ERROR) return -1; // if it's a first call - skip it if (liOldIdleTime.QuadPart != 0) { // CurrentValue = NewValue - OldValue dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime); dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime); // CurrentCpuIdle = IdleTime / SystemTime dbIdleTime = dbIdleTime / dbSystemTime; // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5; //calc Processors for (int i = 0; i < m_iNumberProcessors; i++) { m_PUT[i].dbCurrentTime = Li2Double(m_pSPPI[i].KernelTime) + Li2Double(m_pSPPI[i].UserTime) + Li2Double(m_pSPPI[i].DpcTime) + Li2Double(m_pSPPI[i].InterruptTime) - m_PUT[i].dbOldCurrentTime; m_PUT[i].dbIdleTime = Li2Double(m_pSPPI[i].IdleTime) - m_PUT[i].dbOldIdleTime; // CurrentCpuIdle = IdleTime / SystemTime m_PUT[i].dbIdleTime = m_PUT[i].dbIdleTime / m_PUT[i].dbCurrentTime; // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors m_PUT[i].dbIdleTime = 100.0 - m_PUT[i].dbIdleTime * 100.0 + 0.5; } } // store new CPU's idle and system time liOldIdleTime = SysPerfInfo.liIdleTime; liOldSystemTime = SysTimeInfo.liKeSystemTime; for (int i = 0; i < m_iNumberProcessors; i++) { m_PUT[i].dbOldCurrentTime = Li2Double(m_pSPPI[i].KernelTime) + Li2Double(m_pSPPI[i].UserTime) + Li2Double(m_pSPPI[i].DpcTime) + Li2Double(m_pSPPI[i].InterruptTime); m_PUT[i].dbOldIdleTime = Li2Double(m_pSPPI[i].IdleTime); } return (int)dbIdleTime; } int main() { init(); while( !_kbhit ( )) { printf("%3d%%", GetCpuUsage()); printf("%d", m_iNumberProcessors); for (int i = 0; i < m_iNumberProcessors; i++) { printf(" %.0f%%", m_PUT[i].dbIdleTime); } printf("\n"); /* printf(" %.0f, %.0f |", m_PUT[0].dbIdleTime, m_PUT[0].dbCurrentTime); printf(" %.0f, %.0f |", m_PUT[1].dbIdleTime, m_PUT[1].dbCurrentTime); printf(" %.0f, %.0f |", m_PUT[2].dbIdleTime, m_PUT[2].dbCurrentTime); printf(" %.0f, %.0f |\n", m_PUT[3].dbIdleTime, m_PUT[3].dbCurrentTime);*/ Sleep(1000); } return 0; } |