CPU信息是由一个叫NtQuerySystemInformation()的API来获取的,这个函数在ntdll.dll中,但是并没有一个ntdll.lib与之对应。MSDN推荐用动态加载dll的方式来使用这个函数。
int WIN_GetCpuPerf(WIN_CpuPerfTable& iTbl)
{
// 动态加载dll, 得到NtQuerySystemInformation函数指针
typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);
PROCNTQSI pNtQuerySystemInformation;
pNtQuerySystemInformation = (PROCNTQSI)GetProcAddress(
GetModuleHandleA(“ntdll”),
”NtQuerySystemInformation”
);
if (!pNtQuerySystemInformation)
return -1;
// 获取cpu信息
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION iCpuInfo[16];
ULONG nOutLen = 0;
// 调用函数
pNtQuerySystemInformation(SystemProcessorPerformanceInformation,
(PVOID)iCpuInfo,
sizeof(iCpuInfo),
&nOutLen
);
int nNumCpu = nOutLen / sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
for(int i=0; i<nNumCpu; i++)
{
WIN_CpuPerfEntry entry;
entry.nIdleTime = iCpuInfo[i].IdleTime.QuadPart / 10000; // unit: in 100ns
entry.nKernelTime = iCpuInfo[i].KernelTime.QuadPart / 10000;
entry.nUserTime = iCpuInfo[i].UserTime.QuadPart / 10000;
iTbl.push_back(entry);
}
return 0;
}
那么显然,这个函数并没有直接给出cpu占用率这个信息,而且给出了自开机以来的Idle, Kernel, User的时间。CPU占用百分比是一个实时信息,需要在一段时间内,再计算IdleTime占这段时间的百分比。用100减去这个百分比,就是非Idle的时间。
按理解Idle + Kernel + User就是总时间,不过没验算是不是这样。
ULARGE_INTEGER是一个union,用ULARGE_INTEGER::QuadPart做一个64位整数来计算,其时间单为是100ns。