相关文章推荐
内向的鞭炮  ·  HTML DOM Select ...·  1 年前    · 
阳光的青蛙  ·  Spring ...·  1 年前    · 
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占用率的获得宣告搞定!