为什么ps看到的CPU使用率能大于100%

面试会遇到的一个问题,ps看到的CPU使用率能大于100%,有时候能准确的回答,是在排障的过程中确实见过大于100%的,那么ps命令是如果计算进程CPU使用率的呢?CPU利用率高是经常遇到的问题,常用的系统命令比如sar,pidstat ,mpstat是如何计算CPU使用率的?对于偶发的CPU高,使用ps能准确抓到CPU高的进程吗?

一、通俗的理解CPU使用率

CPU(central processing unit)中央处理器是计算机系统的运算和控制中心,我们写一段代码,经过编译汇编,最终翻译成CPU的指令,CPU就像是一个长跑运动员,我们的代码就像是指令卡,CPU拿着指令,来完成我们要做的事情,比如监听一个端口,读取网络上的数据包,应用程序返回响应;我们把CPU的计算能力比做运动员单位时间能跑的公里数,当前CPU利用率比做当前的单位时间运动员跑了多少除以他的最大能力。为了方便理解,用下面的饼图做一个形象的展示:


image

当然cpu并不是在单位时间内连续的完成一件事情,把相同的事情画到一个饼图方便展示CPU使用率的种类。

二、CPU使用率计算方法

CPU整体的使用率在文件/proc/stat中


stat文件内容

cpu一行依次代表:
name user nice system idle iowait irrq softirq steal guest guest_nice ,
CPU总时间 = user + system + nice + idle + iowait + irq + softirq
命令中看到的各个过程使用率为各个阶段处以总的时间,比如
%user = user/CPU总时间
使用stress命令打压力,两次文件对比,可以看到user状态的数字明显上涨:
stress -c 1


stress测试

top, sar, mpstat这些命令读取/proc/stat文件,根据命令参数的时间间隔采样文件数据,除以时间间隔,计算中最终的CPU使用率;对于单个进程的CPU使用情况,存在文件/proc/pid/stat,pidstat 这个命令会读取这个文件,计算进程使用的CPU使用情况;

三、实验模拟CPU高的场景

通过模拟单核和多核CPU跑满的情况,看下各个命令的处理结果

1.单核打满

go语言模拟单核CPU打满

package main
// CPU test
func main() {
        i := 0
        for {
        //fmt.Println(i)
        i++
        }
}

top命令结果
top-cpu使用图.png

PS命令结果
ps-cpu使用图.png
2.多核打满

多进程代码

package main
func CPU1()() {
        i := 0
        for {
        //fmt.Println(i)
        i++
        }
}
func CPU2()() {
        i := 0
        for {
        //fmt.Println(i)
        i++
        }
}
// CPU test
func main() {
        go CPU1()
        go CPU2()
        i := 0
        for {
        //fmt.Println(i)
        i++
        }
}

TOP结果图
top-cpu.png

PS 结果图
PS-CPU.png
可以看到 main进程占用了超过100% 的CPU
使用top命令查看
top -H
top-H结果.png

htop结果.png

mpstat结果


mpstat.png

四、结论

从多核CPU利用率的结果看到,如果进程使用了多个核,ps命令看到的进程使用率是每个核使用率相加,是会超过100%。
查看man ps中的解释,ps命令计算CPU使用率的方法是

 %cpu   %CPU      cpu utilization of the process in "##.#" format.  Currently, it is the CPU time used divided by the time the process has been running (cputime/realtime ratio),
 expressed as a percentage.  It will not add up to 100% unless you are lucky.  (alias pcpu).

可以看到,ps命令计算CPU使用率的是用CPU使用时间除以进程存活时间,ps算的是所有CPU使用率,而不是单个CPU使用率,所以相加是会大于100%的。
所以,如果要排查CPU使用率高的进程,使用ps并不能准备的反应出当前进程使用的情况,需要使用类似top,pidstat这种实时统计CPU使用率的工具查看。

你可能感兴趣的:(为什么ps看到的CPU使用率能大于100%)