天天看點

擷取CPU使用率

方法如下兩種:

一、擷取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;

繼續閱讀