1. 计算CPU利用率
在Windows中计算CPU利用率的方法是使用SystemProcessorPerformanceInformation参数反复调用NtQuerySystemInformation函数,然后根据返回的IdleTime、KernelTime和UseTime值,分别使用后一次调用获得的值减去前一次调用获得的值,得到各个增量值,然后使用一个除法就可以得到CPU利用率。
这里唯一需要注意的是KernelTime成员值包含IdleTime和核心调用的使用时间。
当使用SystemBasicInformation 调用 NtQuerySystemInformation 来试图获取CPU个数时会失败,返回0xC0000004错误码,可以使用GetSystemInfo函数获得CPU的个数。
CPU利用率的计算公式如下:
100.0 * (IdleTime –PrevIdleTime) / (KernelTime + UserTime – PrevKernelTime – PrevUserTime)
注1:实际内核时间(ActualKernelTime)= KernelTime– IdleTime,内核时间-空闲时间。
注2:全部CPU时间(CpuTime)= UserTime +KernelTime,用户时间+内核时间。
int GetSystemCpuTimes(SystemCpuTimes*cputimes, int num)
{
typedef DWORD (_stdcall *NTQSI_PROC) (int,PVOID, ULONG, PULONG);
// dynamic linking is mandatory to use NtQuerySystemInformation
HINSTANCE hNtDll =LoadLibrary("ntdll.dll");
if (hNtDll == NULL) {
fprintf(stderr, "LoadLibraryntdll.dll failed.\n");
return -1;
}
// gets NtQuerySystemInformation address
NTQSI_PROC NtQuerySystemInformation =(NTQSI_PROC)GetProcAddress(hNtDll, "NtQuerySystemInformation");
if (NtQuerySystemInformation == NULL) {
FreeLibrary(hNtDll);
return -2;
}
// retrieves number of processors
SYSTEM_INFO si;
si.dwNumberOfProcessors = 0;
GetSystemInfo(&si);
if (si.dwNumberOfProcessors == 0)
si.dwNumberOfProcessors = 1;
// allocates an array ofSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION structures, one per processor
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*sppi
= newSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION[si.dwNumberOfProcessors];
if (sppi == NULL) {
FreeLibrary(hNtDll);
return -3;
}
// Get CPU time informations
if (NtQuerySystemInformation(SystemProcessorPerformanceInformation,
sppi, si.dwNumberOfProcessors *
sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION), NULL) != 0) {
FreeLibrary(hNtDll);
delete []sppi;
return -4;
}
// computes system global times summingeach processor value
for (DWORD i = 0; i <si.dwNumberOfProcessors; i++) {
if ((int)i >= num)
break;
// kernel time includes idle time onwindows
// we return only busy kernel timesubtracting
// idle time from kernel time
cputimes[i].user = LO_T *sppi[i].UserTime.QuadPart;
cputimes[i].kernel = LO_T *sppi[i].KernelTime.QuadPart;
cputimes[i].idle = LO_T *sppi[i].IdleTime.QuadPart;
cputimes[i].total = cputimes[i].user + cputimes[i].kernel;
cputimes[i].kernel -= cputimes[i].idle;
}
FreeLibrary(hNtDll);
delete []sppi;
return 0;
}
获取CPU个数
在Windows中可以使用GetSystemInfo函数来获取本机的CPU个数。
int GetNumCpus()
{
SYSTEM_INFO system_info;
memset(&system_info, 0x0,sizeof(system_info));
GetSystemInfo(&system_info);
if (system_info.dwNumberOfProcessors == 0)
return 1;
else
returnsystem_info.dwNumberOfProcessors;
}
2. 获取内存使用情况
在Windows下使用GlobalMemoryStatusEx函数来获取物理内存、虚拟内存和内存页的大小,通过总内存和空闲内存可以计算出内存使用率。
int GetVirtualMem(MemoryInfo &mi)
{
MEMORYSTATUSEX mem_info;
mem_info.dwLength = sizeof(mem_info);
if (!GlobalMemoryStatusEx(&mem_info)) {
memset(&mi, 0x0, sizeof(mi));
return -1;
}
mi.avail_page_file = mem_info.ullAvailPageFile;
mi.avail_phys = mem_info.ullAvailPhys;
mi.avail_virtual = mem_info.ullAvailVirtual;
mi.total_page_file = mem_info.ullTotalPageFile;
mi.total_phys = mem_info.ullTotalPhys;
mi.total_virtual = mem_info.ullTotalVirtual;
mi.usage = (int)(100.0 * (mi.total_phys - mi.avail_phys) /mi.total_phys);
return 0;
}
3. 硬盘使用情况
在Windows下可以使用GetDiskFreeSpaceEx函数来获取该路径下的硬盘使用情况,使用总硬盘大小和空闲硬盘大小可以计算硬盘使用率。
int GetDiskUsage(const char *path, DiskInfo&disk_info)
{
if (path == NULL)
path = "C:\\";
ULARGE_INTEGER caller, total, free;
if (GetDiskFreeSpaceEx(path, &caller, &total, &free) == 0) {
memset(&disk_info, 0x0, sizeof(disk_info));
return -1;
}
disk_info.free= free.QuadPart;
disk_info.total = total.QuadPart;
disk_info.usage = (int)(100.0 * (disk_info.total - disk_info.free) /disk_info.total);
return 0;
}
4. 系统启动时间
在Windows下可以使用GetTickCount64函数来获取系统的运行时间,它输出一个64位的毫秒值,通过除以1000可以获得系统的运行秒值。
double GetSystemBootTime()
{
return GetTickCount64() / 1000.0f; // return seconds.
}