今天在7DGroup的群里,老郑提了个问题,ps统计出来的CPU百分比为什么比TOP统计出来的少很多。图如下:
从上面的图来加一下,确实差别比较大呀。
top里面:
800%-16.9%-7.6%-22.1%-29.9%-8.8%-24.4%-16.9%-20.3%=653.1%
ps里面只有300%以下。
为什么会这样呢?
先得了解ps和top有什么区别。
Top是一个monitoring tool,但ps是一个snapshot tool。这是一个本质的区别。
ps是取当前数据的,从/proc/pid目录中取出来。
top是在一直取数据,并且根据刷新周期做计算的。
ps怎么计算CPU的呢?
有几参数如下:
系统启动时间: 是系统自启动以来的总时间长度。
线程启动时间:线程启动的时间点。
线程CPU时间:线程用CPU的时间长度。
线程时间 = 系统启动时间 - 线程启动时间
线程CPU使用率 = 线程CPU时间*1000/线程时间
计算出的CPU使用率百分比 = 线程CPU使用率/10 . 线程CPU使用率%10
系统启动时间: 15456374.085712
线程启动时间:9470058.848042
线程CPU时间:987163
线程时间 = 15456374.085712 - 9470058.848042 = 5986315.23767
线程CPU使用率 = 987163 * 1000 / 5986315.23767 = 164.9
计算出的CPU使用率百分比 = 164.9 / 10 . 164.9%10 = 16.5
所以ps计算百分比的数据取自/proc/目录。
从/proc/<pid>/stat取出如下几个时间。
utime:用户模式的CPU时间消耗。
stime:内核模式的CPU时间消耗。
cutime:用户模式的CPU时间消耗,包括子进程。
cstime:内核模式的CPU时间消耗,包括子进程。
starttime:线程启动时间点。
时间消耗是通过CPU时间片来统计的。计算的基础就是CPU时间片,CPU频率就是每秒内的CPU计算次数(但是单精双精浮点运算时CPU时间片是不一样的,这个要注意下)。
下面我们只从取出的值的结果来做计算。
如果想用ps像top一样计算一定时间周期内的CPU使用率,可以按如下方式计算。
[root@7dgroup 2287]# ps -p 2287 -o %cpu,cputime,etime,etimes
%CPU TIME ELAPSED ELAPSED
0.3 00:00:00 01:03 63
这里有两个参数,etime和etimes(这两个参数的header都是ELAPSED),这两个参数别是:
etime:线程自启动以来的持续时间,格式是[DD-]hh:]mm:ss。
etimes:线程自启动以来的持续时间,以秒为单位。
比如说,上面这个2287进程,在第一次取值时,如上所示。
要计算到当前时间消耗了多少CPU,需要再取一次数据。
[root@7dgroup 2287]# ps -p 2287 -o %cpu,cputime,etime,etimes
%CPU TIME ELAPSED ELAPSED
0.3 00:00:01 04:30 270
计算一下时间:
前一次取值时:
CPU时间片消耗是:0(00*3600+00*60+00)
CPU时间窗口是63。计算过程是:1*60+3 = 63.
后一次取值时:
CPU时间片消耗是:1(00*3600+00*60+1)
CPU时间窗口是270。计算过程是:4*60+30 = 270.
CPU使用率计算是:
((1-0)/(270-63))*100 = 0.4
所以这个进程在这段时间内所用的CPU百分比是0.4%。
有兴趣的也可以撸一下ps的源代码。
如果对top计算结果有异议的,也可以去撸下top的源码。
上面逻辑了这么多,那么我们在看一个系统的资源使用率时,要看ps还是top呢?
ps和top的关系如下所示:
top是一个时间周期内的资源统计。
ps是一个个时间点的资源值。
所以如果要监控一个系统的整体资源使用率的话,建议用top来看。
如果要分析到一个具体的线程使用的CPU资源时,再用ps来看。