浅谈Linux下CPU利用率和CPU负载及其代码实现原理
编者注: 本来想写个简单的程序测试CPU利用率,后来代码实现后与top(ps)命令测试的结果做对比,疑惑了,疑惑后有了此文……
本来就是想通过写个小程序测试CPU利用率从而可以检验其他的工具性能之类的数据,后来参照IPbench中的cpu_target_lukem插件实现我们的功能,简单描述下原理:我们运行一个优先级很低的进程,它占有了CPU的闲暇时间,我们用CPU某段循环内闲暇时间除以该时段总时间则可得到CPU利用率。主要功能实现代码如下:
x0 = get_cycles(); //last cycle count values while (calc) { x1 = x0; //last cycle count values gives to x1 x0 = get_cycles(); //the current count values delta = x0 - x1; // ?t total += delta; //adds ?t to a running total/* If the delta looks like less than a context switch,add this to idle time; otherwise add it to busy time */ if (delta < PROFILE_CONTEXT_COST) idle += delta; timer_buffer.idle = idle; timer_buffer.total = total; }之后我们编译运行本程序,程序输出为:
[11:43.32] dbg: Average CPU time is 5.2
[11:43.34] dbg: Average CPU time is 5.2
这时候我们使用 " ps -au "命令,会找到这一条信息:
long 11741 95.7 0.0 19668 520 pts/16 SNl+ 11:40 2:58 ./a.out
熟悉ps命令的童鞋们知道,long为该进程所属用户;11741为该进程的PID号;95.7表示该进程的CPU占用率为95.7%;0.0表示该进程的物理内存占用率为0%;19668表示该进程占用了多少虚拟内存量;520表示该进程占用了多少固定内存量;pts/16表示登陆端口;SNl+为和上面介绍的进程状态一样(R/S/D/T/Z进程);11:40为该进程触发启动的时间; 2:58表示该进程占用CPU的时间;./a.out表示触动该进程的命令 。所以ps命令显示的是我们a.out的CPU利用率高达95.7%。
接着,我做了第二个测试,我把a.out拷贝了一份b.out,同时运行他们我们会看到如下信息:
a.out 显示的 :
[11:47.50] dbg: Average CPU time is 6.1
[11:47.52] dbg: Average CPU time is 6.1
b.out 显示的s :
[11:48.20] dbg: Average CPU time is 10.2
[11:48.22] dbg: Average CPU time is 10.2
这时候我使用 "ps -au" 再查看a.out和b.out信息如下:
long 11741 94.1 0.0 19668 520 pts/16 SNl+ 11:40 7:26 ./a.out
long 11905 90.9 0.0 19668 516 pts/17 SNl+ 11:46 2:08 ./b.out
卧槽,顿时崩溃啊!到了这,我产生了三个疑问:第一、为毛运行a.out和b.out显示的CPU利用率不一样……第二、为毛在ps中显示的a.out和b.out的CPU利用率不一样?第三、为毛ps中a.out和b.out的CPU利用率分别为94.1%和90.0%,而两者加一起远远大于100%?!!我晕了,那Linux到底是如何定义CPU利用率的呢?
参数解释user (426215) 从系统启动开始累计到当前时刻,用户态的CPU时间(单位:jiffies) ,不包含 nice值为负进程。1jiffies=0.01秒nice (701)从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间(单位:jiffies)system (115732)从系统启动开始累计到当前时刻,核心时间(单位:jiffies)idle (2023866)从系统启动开始累计到当前时刻,除硬盘IO等待时间以外其它等待时间(单位:jiffies)iowait (27329)从系统启动开始累计到当前时刻,硬盘IO等待时间(单位:jiffies) ,irq (4)从系统启动开始累计到当前时刻,硬中断时间(单位:jiffies)softirq (557) 从系统启动开始累计到当前时刻,软中断时间(单位:jiffies)
CPU时间=user+system+nice+idle+iowait+irq+softirq
“intr”这行给出中断的信息,第一个为自系统启动以来,发生的所有的中断的次数;然后每个数对应一个特定的中断自系统启动以来所发生的次数。
“ctxt”给出了自系统启动以来CPU发生的上下文交换的次数。
“btime”给出了从系统启动到现在为止的时间,单位为秒。
“processes (total_forks) 自系统启动以来所创建的任务的个数目。
“procs_running”:当前运行队列的任务的数目。
“procs_blocked”:当前被阻塞的任务的数目。
那么CPU利用率可以使用以下两个方法。先取两个采样点,然后计算其差值:cpu usage=(idle2-idle1)/(cpu2-cpu1)*100
cpu usage=[(user_2 +sys_2+nice_2) - (user_1 + sys_1+nice_1)]/(total_2 - total_1)*100
第四节 Linux提供的一些查看系统信息的工具使用下面这些命令我们可以查询总的CPU使用率、单独的CPU使用率(对于对称多处理机器SMP)、从你上次启动后的平均CPU使用率等。
4.1 老当益壮的top命令
使用top命令可以动态的查看CPU使用率。它会现实当前内核管理着的任务信息,它还会显示上线时间、负载均值、物理和交换内存使用状况。使用如下: $ top
按Q键推出top。
4.2 使用"mpstat"命令
使用这个命令,你需要先安装sysstat工具,对于Debian或Ubuntu用户,可以通过apt-get直接安装:
$ apt-get install sysstat
使用如下命令查看CPU使用率信息:
$ mpstat
使用如下命令可以监控单独的CPU使用率信息:
$ mpstat -P ALL
4.3 使用"sar"命令
使用sar命令显示CPU使用率的语法如下:
$ sar -u 2 5 ( sar [ 选项 ] [ <时间间隔> [ <次数> ] ])
这条命令会现实2秒内的CPU使用率,总共显示5次。
4.4 使用"iostat"命令
"iostat"命令可以用来查询从系统启动以来的是CPU平均使用率以及设备或者分区的I/O状况:
$ iostat
4.5 GUI Tools 一些有图形界面的工具
KDE桌面环境有一些系统监控器一类的工具可以用来监控CPU使用率甚至更多的系统信息(比如说CPU负载状况、物理内存以及交换分区的数据占用信息),你还可以使用它来杀死一些进程。
下表总结了若干Linux下的工具:
工具
简单介绍
top
查看进程活动状态以及一些系统状况
vmstat
查看系统状态、硬件和系统信息等
iostat
查看CPU 负载,硬盘状况
sar
综合工具,查看系统状况
mpstat
查看多处理器状况
netstat
查看网络状况
iptraf
实时网络状况监测
tcpdump
抓取网络数据包,详细分析
mpstat
查看多处理器状况
tcptrace
数据包分析工具
netperf
网络带宽工具
dstat
综合工具,综合了 vmstat, iostat, ifstat, netstat 等多个信息
【注】: [1] http://server.51cto.com/sCollege-188250.htm [2] http://en.wikipedia.org/wiki/Load_%28computing%29 [3] http://www.linuxjournal.com/article/9001 [4] http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages [5] http://blog.csdn.net/longerzone/article/details/8628756 ([4]的中文翻译版) [6] http://www.jb51.net/LINUXjishu/34607.html