方法如下兩種:
一、擷取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;
}