【发布时间】:2017-02-07 22:04:48
【问题描述】:
我一直在使用以下方法获取整台计算机的当前 CPU 利用率:
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
//Use a simple infinite loop to display the concept
for(;; ::Sleep(500))
{
COORD coord = {0, 0};
SetConsoleCursorPosition(hOut, coord);
int nCpuUse = get_cpu_utilization_method_01();
_tprintf(L"CPU Usage: %d\t", nCpuUse);
}
int get_cpu_utilization_method_01()
{
int nRes = -1;
FILETIME ftIdle, ftKrnl, ftUsr;
if(GetSystemTimes(&ftIdle, &ftKrnl, &ftUsr))
{
static BOOL bUsedOnce = FALSE;
static ULONGLONG uOldIdle = 0;
static ULONGLONG uOldKrnl = 0;
static ULONGLONG uOldUsr = 0;
ULONGLONG uIdle = ((ULONGLONG)ftIdle.dwHighDateTime << 32) | ftIdle.dwLowDateTime;
ULONGLONG uKrnl = ((ULONGLONG)ftKrnl.dwHighDateTime << 32) | ftKrnl.dwLowDateTime;
ULONGLONG uUsr = ((ULONGLONG)ftUsr.dwHighDateTime << 32) | ftUsr.dwLowDateTime;
//Only if we have previous values
if(bUsedOnce)
{
ULONGLONG uDiffIdle = uIdle - uOldIdle;
ULONGLONG uDiffKrnl = uKrnl - uOldKrnl;
ULONGLONG uDiffUsr = uUsr - uOldUsr;
if(uDiffKrnl + uDiffUsr)
{
//Calculate percentage
nRes = (int)((uDiffKrnl + uDiffUsr - uDiffIdle) * 100 / (uDiffKrnl + uDiffUsr));
//Check value and correct it (Just in case)
if(nRes < 0)
nRes = 0;
else if(nRes > 100)
nRes = 100;
}
}
//Remember previous data
bUsedOnce = TRUE;
uOldIdle = uIdle;
uOldKrnl = uKrnl;
uOldUsr = uUsr;
}
return nRes;
}
但是从 Windows 10 开始,我收到了来自我的软件用户的报告,表明这种方法提供的读数可能是错误的。有人告诉我,它可以报告低至 Windows Task Manager 显示的值的一半。
我自己的测试已经运行了一段时间,它似乎有点接近笔记本电脑上的Task Manager 读数,但是当我在使用 Intel Core i7-4770 CPU @ 3.40 的台式机上运行它时具有 4 个物理内核和 8 个逻辑内核的 GHz,读数似乎始终过低:
请注意,我将 Windows 7 安装在相同的硬件上(现在运行 Windows 10),然后它在 Windows 7 上运行得非常可靠。
那么有什么想法可以让它在 Windows 10 下运行吗?
【问题讨论】:
-
使用性能计数器
-
@DavidHeffernan:你知道,有趣的是
taskmgr.exe本身不使用performance counters或pdh.dll -
@c00000fd - 我通过this way 计算每个进程和空闲进程(这是 100 -
CPU utilization for the entire computer)的 cpu 使用率,在 win10 上我得到了与 taskmgr 相同的结果。但这是使用本机 api 和时间来自SYSTEM_PROCESS_INFORMATION
标签: c++ windows winapi windows-10 cpu-usage