#include <iostream>
#include <iomanip>
#include <windows.h>
using namespace std;
int CompareFileTime(FILETIME time1, FILETIME time2)
{
int a = time1.dwHighDateTime << 32 | time1.dwLowDateTime ;
int b = time2.dwHighDateTime << 32 | time2.dwLowDateTime ;
return (b - a);
}//原文用的是_int64类型,但是我的电脑是32位Windows系统,安全考虑用int
//这个函数这样写到底对不对,还需要商榷。即使是原文,后面调用这个函数时,
//左值也是int型的,所以_int64肯定有问题。那么改成int后这个算法要推敲。
int main(){
FILETIME idleTime;
FILETIME kernelTime;
FILETIME userTime;
bool res;
res = GetSystemTimes(&idleTime, &kernelTime, &userTime);
cout << "res = " << res << 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 );
int idle = CompareFileTime(pre_idleTime,idleTime);
int kernel = CompareFileTime(pre_kernelTime, kernelTime);
int user = CompareFileTime(pre_userTime, userTime);
int cpu_occupancy_rate = (kernel + user - idle) * 100 / (kernel+user);
//(总的时间 - 空闲时间)/ 总的时间 = 占用cpu的时间,也就是占用率
int cpu_idle_rate = (-idle) * 100 / (kernel + user);
//应该是正值还是负值?
cout << left << setw(10) << "CPU占用率:" << cpu_occupancy_rate << "%" << endl
<< setw(10) << "CPU闲置率:" << cpu_idle_rate << "%" << endl << endl;
pre_idleTime = idleTime;
pre_kernelTime = kernelTime;
pre_userTime = userTime;
}
return 0;
}
测试结果虽然是CLI界面,但是是动态推进的:
这个代码中有不少技术亮点,值得好好研究。
编译器的警告提示:
加上运行结果中CPU占用率与闲置率的和并不是100%,而且我还在局部变量idle前面加了一个负号,才让两个比率都是正值——所以我有理由怀疑:这个网上拷来的代码其实是错的!如何修改,待后期研究。
=============================== 菜鸟的分割线 =================================
菜鸟啊菜鸟!我的确是菜鸟!T_T!今天9月5日上午经过仔细研究后,发现FILETIME结构体的两个成员到底是什么意思了!原来是两个双字节数拼起来表示时间的,一个双字节是高32位,另一个是低32位,最终拼在一起表示一个64位字长的文件时间变量!所以用__int64(注意前面必须有连续的两条下划线)作为CompareFiletime函数的参数类型和返回类型,都是对的!另外GetSystemTimes的三个参数,一个是闲置时间,一个是核心态时间,一个是用户态时间。可以在算出CPU占用率和闲置率的同时,还算出核心态占用比率、用户态占用比率!这样对CPU的负载监视更加清楚、精确!修改后的代码如下:
#include <iostream>
#include <iomanip>
#include <windows.h>
using namespace std;
__int64 CompareFileTime(FILETIME time1, FILETIME time2)
{
__int64 a = time1.dwHighDateTime << 32 | time1.dwLowDateTime ;
__int64 b = time2.dwHighDateTime << 32 | time2.dwLowDateTime ;
return (b - a);
}//经过对FILETIME structure的两个参数的研究,发现用__int64类型是对的!
//只要操作正确,__int64类型数据也不会导致在32位系统上出现不安全的错误。
int main(){
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 = CompareFileTime(pre_idleTime, idleTime);
__int64 kernel = CompareFileTime(pre_kernelTime, kernelTime);
__int64 user = CompareFileTime(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;
}
return 0;
}
当打开某个程序时,比如开一个网页,核心态占比率会迅速下降,同时用户态占比率迅速上升。截图中第5段、第6段数据显示的就是我打开一个网页时,CPU文件时间的变化情况,不仅CPU占用率迅速上升,而且用户态占比率也迅速上升。在第7段数据时,CPU占比率和用户态占比率同时下降,这个时间只用了2 * 500ms = 1s。
第6章负载监视器设计的第一个底层接口:CPU占用率的获得宣告搞定!