在前面介绍了如何获取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中,空闲时间可能大于运行时间,所以需要将运行时间乘以核心数就是总的运行时间,然后来计算使用率