在前面介绍了如何获取CPU使用率、如何获取线程的CPU使用率等,但是有个疑问,CPU是如何来计算使用率的?

1 时间中断

先说一个概念,时间中断。在Linux系统中,0号的中断是一个定时器中断。在固定的时间间隔内发生一次中断,每次中断都会定时更新系统的日期时间、更新CPU统计数用于时间片轮转来调度进程切换。

而上面的“固定的时间”,在用户空间,叫做USER_HZ,一般其值是100,即每秒中断100次,在内核文件include/asm-generic/param.h中定义了它的值:

# undef HZ
# define HZ     CONFIG_HZ   /* Internal kernel timer frequency */
# define USER_HZ    100     /* some user interfaces are */
# define CLOCKS_PER_SEC (USER_HZ)       /* in "ticks" like times() */

PS:在内核空间,则是CONFIG_HZ 来表示时间中断的频率

2 /proc/stat

在虚拟文件系统proc中的stat展示的系统CPU任务统计信息。
使用指令,查看:

# cat /proc/stat                                             
cpu  2191 0 96075 411703 49 0 265 0 0 0
cpu0 1013 0 46249 207320 37 0 265 0 0 0
cpu1 1178 0 49826 204383 12 0 0 0 0 0
.......

我们通过man proc查看上面显示的数据含义,上面各个数据表示的是系统在各种状态下花费的时间,其单位正是上面说的USER_HZ,即1/100s。
上面的CPU0、CPU1表示不同的CPU核,而最上面的CPU则是所有CPU的累加。
上面有10组数字,具体每组数据的含义如下:

1

user(us)

用户态CPU时间

2

nice(ni)

低优先级用户态时间

3

system(sys)

内核态CPU时间

4

idel(id)

空闲时间

5

iowait(wa)

等待I/O的时间

6

irq(hi)

处理硬中断的时间

7

softirq(si)

处理软中断的时间

8

steal(st)

在虚拟化环境中运行时在其他操作系统中花费的时间

9

guest(guest)

为在 Linux 内核控制下的客户操作系统运行虚拟 CPU 所花费的时间

10

guest_nice(gnice)

低优先级运行虚拟CPU花费的时间

计算CPU的使用率,就是除了空闲时间之外,其它时间占CPU总时间的百分比。上面的时间为设备从开机的累计实际时间,如果要计算实时或者某段时间的CPU使用率,那么系统就会取段一时间(比如top指令的默认3S),计算这一段时间的差值来计算CPU的使用率。

3 /proc/uptime

我们也可以查看/proc/time里面的值,来计算CPU的使用率

# cat /proc/uptime                                           
12454.99 20093.08

上面第一个数值是开机运行时间,单位为S,第二个数为空闲时间,单位为S。在多核的CPU中,空闲时间可能大于运行时间,所以需要将运行时间乘以核心数就是总的运行时间,然后来计算使用率