一、获取CPU使用率常用方法如下,当时该方法说明使用在2000 和 xp,随后系统不可用
不过测试,在win2003 下是可行的,在win2008 win7 下将会失败,查资料有NtQuerySystemInformation
的升级版NtQuerySystemInformationEx 不过没找到资料……
typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);
PROCNTQSI NtQuerySystemInformation;
typedef BOOL (WINAPI *PGETSYSTIMES)(LPFILETIME ,LPFILETIME,LPFILETIME);
PGETSYSTIMES GetSysTimes;
#include <stdio.h> #include <string> #include <windows.h> #include <conio.h> using namespace std; #define SystemBasicInformation 0 #define SystemPerformanceInformation 2 #define SystemTimeInformation 3 #define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart)) #define GETPROADDR_ERR 0x00000003 //系统基本信息结构体 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; long CCPUInfo::GetCpuSpeed1(double &tCpuUsed) { SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo; SYSTEM_TIME_INFORMATION SysTimeInfo; SYSTEM_BASIC_INFORMATION SysBaseInfo; double dbIdleTime; double dbSystemTime; LONG status = 0; LARGE_INTEGER liOldIdleTime = {0,0}; LARGE_INTEGER liOldSystemTime = {0,0}; NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(GetModuleHandle(L"ntdll"),"NtQuerySystemInformation"); if (!NtQuerySystemInformation) return GETPROADDR_ERR; // 获得本机处理器个数 status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL); if (status != NO_ERROR) return status; while(!_kbhit()) { // 获得新的系统时间 status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0); if (status!=NO_ERROR) return status; // 获得一个新的CPU idle时间 2008下该函数出错 status =NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL); if (status != NO_ERROR) return status; // 获取CPU使用率 if (liOldIdleTime.QuadPart != 0) { // CPU使用率为新的时间-旧的时间 dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime); dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime); // 获得CPU使用情况 dbIdleTime = dbIdleTime / dbSystemTime; //获得CPU使用率 dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5; if((UINT)dbIdleTime != 0) { tCpuUsed = (double)dbIdleTime; break; } } // 获得新的CPU's idle和系统时间 liOldIdleTime = SysPerfInfo.liIdleTime; liOldSystemTime = SysTimeInfo.liKeSystemTime; // 延时一秒 Sleep(100); } if(tCpuUsed > 100) { tCpuUsed = 100; } if(tCpuUsed < 0) { tCpuUsed = 1; } return status; }
二、普通方法获取CPU:
__int64 CCPUInfo::CompareFileTime ( FILETIME time1, FILETIME time2 ) { __int64 a = time1.dwHighDateTime << 32 | time1.dwLowDateTime ; __int64 b = time2.dwHighDateTime << 32 | time2.dwLowDateTime ; return (b - a); } long CCPUInfo::GetCpuSpeed(double &tCpuUsed) { HANDLE hEvent; BOOL res ; LONG status = 0; // FILETIME preidleTime; FILETIME prekernelTime; FILETIME preuserTime; // FILETIME idleTime; FILETIME kernelTime; FILETIME userTime; HINSTANCE hKernel = LoadLibrary( _T("Kernel32.dll") ); if (hKernel == NULL) { return (GetLastError()); } GetSysTimes = (PGETSYSTIMES)GetProcAddress(hKernel,"GetSystemTimes"); if( GetSysTimes == NULL ) { return (GetLastError()); } res = GetSysTimes( &idleTime, &kernelTime, &userTime ); if (!res) { return GetLastError(); } preidleTime = idleTime; prekernelTime = kernelTime; preuserTime = userTime ; hEvent = CreateEvent (NULL,FALSE,FALSE,NULL); // 初始值为 nonsignaled ,并且每次触发后自动设置为nonsignaled while (1) { WaitForSingleObject( hEvent,500); //等待500毫秒 res = GetSysTimes( &idleTime, &kernelTime, &userTime ); if (!res) { return GetLastError(); } __int64 idle = CompareFileTime( preidleTime,idleTime); __int64 kernel = CompareFileTime( prekernelTime, kernelTime); __int64 user = CompareFileTime(preuserTime, userTime); double cpu = (((double)(kernel + user - idle)/(double)(kernel+user))*100+0.5); if((UINT)cpu != 0) { tCpuUsed = cpu; break; } preidleTime = idleTime; prekernelTime = kernelTime; preuserTime = userTime ; } if(tCpuUsed > 100) { tCpuUsed = 100; } if(tCpuUsed < 0) { tCpuUsed = 1; } return status; }