项目需要获取cpu的使用率,还需要跟任务管理器保持一致.
先是百度了一大圈,说是用GetSystemTimes这个api,来获取cpu总时间和空闲时间,然后做减法,每一段时间循环计算来实现的。
下面是代码:
__int64 CompareTime(FILETIME time1, FILETIME time2)
{
__int64 a = time1.dwHighDateTime << 32 | time1.dwLowDateTime;
__int64 b = time2.dwHighDateTime << 32 | time2.dwLowDateTime;
return (b - a);
}
void TestDiskManager::GetCpuInfo()
{
FILETIME idleTime;//空闲时间
FILETIME kernelTime;//核心态时间
FILETIME userTime;//用户态时间
bool res;
res = GetSystemTimes(&idleTime, &kernelTime, &userTime);
cout << "GetSystemTimes(&, &, &) = " << res << endl << endl;
HANDLE hEvent;
FILETIME pre_idleTime;
FILETIME pre_kernelTime;
FILETIME pre_userTime;
pre_idleTime = idleTime;
pre_kernelTime = kernelTime;
pre_userTime = userTime;
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
//初始值为nonsignaled,并且每次触发后自动设置为nonsignaled
while (1) {
WaitForSingleObject(hEvent, 1000);//等待500毫秒
res = GetSystemTimes(&idleTime, &kernelTime, &userTime);
__int64 idle = CompareTime(pre_idleTime, idleTime);
__int64 kernel = CompareTime(pre_kernelTime, kernelTime);
__int64 user = CompareTime(pre_userTime, userTime);
int cpu_occupancy_rate = (kernel + user - idle) * 100 / (kernel + user);
//(总的时间 - 空闲时间)/ 总的时间 = 占用CPU时间的比率,即占用率
int cpu_idle_rate = idle * 100 / (kernel + user);
//空闲时间 / 总的时间 = 闲置CPU时间的比率,即闲置率
int cpu_kernel_rate = kernel * 100 / (kernel + user);
//核心态时间 / 总的时间 = 核心态占用的比率
int cpu_user_rate = user * 100 / (kernel + user);
//用户态时间 / 总的时间 = 用户态占用的比率
cout << left << setw(15) << "CPU占用率:" << cpu_occupancy_rate << "%" << endl
<< setw(15) << "CPU闲置率:" << cpu_idle_rate << "%" << endl
<< setw(15) << "核心态占比率:" << cpu_kernel_rate << "%" << endl
<< setw(15) << "用户态占比率:" << cpu_user_rate << "%" << endl << endl;
pre_idleTime = idleTime;
pre_kernelTime = kernelTime;
pre_userTime = userTime;
}
}
void TestDiskManager::GetCpuInfo2()
{
static FILETIME pre_idle_time;
static FILETIME pre_kernel_time;
static FILETIME pre_user_time;
// 空闲时间
FILETIME idle_time;
// 内核时间
FILETIME kernel_time;
// 用户时间
FILETIME user_time;
BOOL ret = GetSystemTimes(&idle_time, &kernel_time, &user_time);
int idle = CompareFileTime(&pre_idle_time, &idle_time);
int kernel = CompareFileTime(&pre_kernel_time, &kernel_time);
int user = CompareFileTime(&pre_user_time, &user_time);
float rate = (kernel + user - idle) / (1.0 * (kernel + user));
pre_idle_time = idle_time;
pre_kernel_time = kernel_time;
pre_user_time = user_time;
cout << left << setw(15) << "CPU占用率:" << rate << "%" << endl;
}
然后发现,跟任务管理器显示偏差很大,然后就去搜索原因,百度了一圈也没找到,都是类似的解决,没人说出个所以然来,最后在stackoverflow找到一个靠谱的答案,
相关截图:
大意是讲taskmgr(任务管理器)是超线程感知的。假设您有 2 个物理内核,总共有 4 个逻辑内核。将2个内核置于满负荷状态,任务列表将显示100%,而您的方法将显示50%,当所有4个逻辑内核都填满时,任务列表仍将显示100%,然后您的方法也将显示100%。
文中也没给解决方案,于是继续搜索。最后在stack大佬的帮助下,找到了这篇文章:
PerformanceCounter reporting higher CPU usage than what's observed
截图:
大意是讲,使用了错误的参数。使用“Processor Information”而不是“Processor”。
结合之前找到的命令:
typeperf "\Processor(_Total)\% Processor Time"
稍作修改为:
typeperf "\Processor Information(_Total)\% Processor Utility"
试了下果然可行,数据什么的都很准确,如下图:
至此,基本上算是可以交差了。
不过在实现的过程中发现,做C++,面向百度编程已经不行了,必须要面向谷歌编程了。国内C++相关的干货实在太少,虽然天下文章一大抄,但是无脑抄就不太好了。