计算CPU利用率

CPU的使用率其实是一段时间内的统计数据,按照定义,某个进程的CPU使用率是指该进程在一个时间段内消耗的CPU时间与该时间段长度的比值。所以选择不同的时间间隔,得到的结果是不同的。

在Windows系统下,我们可以用 GetSystemTimesGetProcessTimes 等API获得一个时间段内的CPU时间。下面结合使用体会说明如何计算系统CPU使用率。

1.计算原理

系统将时间以时间片的形式分配给CPU,时间片是系统的最小时间单位,在一个时间片内CPU可能在处理用户程序,可能在处理系统程序,也可能处于空闲状态,我们只要统计在一段时间内空闲的总时间与工作的总时间,就能得到这段时间的CPU平均使用率。

在Windows系统中,系统启动后就会记录每个时间片的状态,并存放在内存的变量中。假如系统在内存中有3个变量:Parameter_Idle,Parameter_Kernel,Parameter_User,则这三个变量分别记录了从系统启动开始到当前的各个时间片的累加值,即Parameter_Idle记录了从系统开始到当前的总的空闲时间片数,Parameter_Kernel记录了从系统开始到当前的总的KernelMode状态的时间片数。

如图上标识,在Start时间点获取一次系统的当前各个状态的时间片数,在End时间点再次获取一次系统的当前各个状态的时间片数。两个时间点获取的各个状态的时间片数量的差值,然后

就是统计时间内,CPU的使用率

2.C++代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
static float CalculateCPULoad(unsigned long long idleTicks, unsigned long long totalTicks)
{
static unsigned long long _previousTotalTicks = 0;
static unsigned long long _previousIdleTicks = 0;

unsigned long long totalTicksSinceLastTime = totalTicks - _previousTotalTicks;
unsigned long long idleTicksSinceLastTime = idleTicks - _previousIdleTicks;

float ret = 1.0f -
((totalTicksSinceLastTime > 0) ? ((float)idleTicksSinceLastTime) / totalTicksSinceLastTime : 0);

_previousTotalTicks = totalTicks;
_previousIdleTicks = idleTicks;
return ret;
}

static unsigned long long FileTimeToInt64(const FILETIME & ft)
{
return (((unsigned long long)(ft.dwHighDateTime)) << 32) | ((unsigned long long)ft.dwLowDateTime);
}


float GetCPULoad()
{
FILETIME idleTime, kernelTime, userTime;
return GetSystemTimes(&idleTime, &kernelTime, &userTime) ?
CalculateCPULoad(FileTimeToInt64(idleTime), FileTimeToInt64(kernelTime) + FileTimeToInt64(userTime))
: -1.0f;
}

void main()
{
float cpu=0;
while (true)
{
Sleep(1000);//统计1s内的CPU平均使用率
cpu = 100 * GetCPULoad();
}
}
虽然很不要脸,但是还请您多多打赏 ^_^