Linux环境下进程的CPU占用率

1、Linux环境下查看CPU信息

1.1、查看CPU详细信息

通过cat /proc/cpuinfo命令,可以查看CPU相关的信息

[root@rh ~]$ cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 44
model name : Intel(R) Xeon(R) CPU           E5620  @ 2.40GHz
stepping : 2
cpu MHz : 1596.000
cache size : 12288 KB
physical id : 0
siblings : 8
core id : 0
cpu cores : 4
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 11
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 popcnt aes lahf_lm arat epb dts tpr_shadow vnmi flexpriority ept vpid
bogomips : 4800.15
clflush size : 64
cache_alignment : 64
address sizes : 40 bits physical, 48 bits virtual
power management:

  

 

在查看到的相关信息中,通常有些信息比较让人迷惑,这里列出一些解释:

  • physical id: 指的是物理封装的处理器的 id。
  • cpu cores: 位于相同物理封装的处理器中的内核数量。
  • core id: 每个内核的 id。
  • siblings: 位于相同物理封装的处理器中的逻辑处理器的数量。
  • processor: 逻辑处理器的 id。

我们通常可以用下面这些命令获得这些参数的信息:

[root@rh ~]$ cat /proc/cpuinfo | grep "physical id" | sort|uniq
physical id     : 0
physical id     : 1
[root@rh ~]$ cat /proc/cpuinfo | grep "cpu cores" | sort|uniq
cpu cores     : 4
[root@rh ~]# cat /proc/cpuinfo | grep "core id" | sort|uniq
core id          : 0
core id          : 1
core id          : 10
core id          : 9
[root@rh ~]$ cat /proc/cpuinfo | grep "siblings" | sort|uniq
siblings     : 8
[root@rh ~]$ cat /proc/cpuinfo | grep "processor" | sort|uniq
processor     : 0
processor     : 1
processor     : 10
processor     : 11
processor     : 12
processor     : 13
processor     : 14
processor     : 15
processor     : 2
processor     : 3
processor     : 4
processor     : 5
processor     : 6
processor     : 7
processor     : 8
processor     : 9

 

通过上面的结果,可以看出这台机器:

  • 1)有 2 个物理封装的处理器(physical id 有 2 个);
  • 2)每个物理封装的处理器有 4 个内核(cpu cores 为 4);
  • 3)每个物理封装的处理器有 8 个逻辑处理器(siblings 为 8),可见台机器的处理器开启了超线程技术,每个内核(core)被划分为了 2 个逻辑处理器(processor);
  • 4)总共有 16 个逻辑处理器(processor 有 16 个);

超线程技术:超线程技术就是利用特殊的硬件指令,把两个逻辑内核模拟成两个物理芯片,让单个处理器都能使用线程级并行计算,进而兼容多线程操作系统和软件,减少了CPU的闲置时间,提高的CPU的运行效率。

 

1.2、查看多核CPU信息

可以使用mpstat命令或sar命令查看。具体使用可以通过man mpstat/sar来查看

 

2、在Linux环境下计算进程的CPU占用

2.1、通过/proc/stat文件查看所有的CPU活动信息

下面实例数据是内核2.6.24-24版本以上的:

[root@rh ~]$ cat /proc/stat
cpu  223447 240 4504182 410802165 59753 412 586209 0 0
cpu0 17625 11 193414 25755165 34590 72 16780 0 0
cpu1 12412 9 139234 25860912 1139 27 15697 0 0
cpu2 14953 0 558618 25310182 230 73 87851 0 0
cpu3 4088 0 138057 25873479 3404 19 15862 0 0
cpu4 13417 17 161123 25829756 10429 22 17155 0 0
cpu5 23935 5 331837 25605479 369 20 26095 0 0
cpu6 19320 0 319132 25619728 2060 18 30690 0 0
cpu7 18430 0 324300 25616142 4170 20 33081 0 0
cpu8 31940 0 661718 25231911 1474 15 67661 0 0
cpu9 8079 87 152035 25829339 237 19 16308 0 0
cpu10 4247 24 140052 25869331 168 18 15059 0 0
cpu11 16305 4 401473 25567904 207 14 34674 0 0
cpu12 8227 0 157815 25853353 319 10 14808 0 0
cpu13 18894 46 479709 25354279 653 26 157885 0 0
cpu14 7000 30 204760 25769743 159 16 21059 0 0
cpu15 4567 1 140899 25855452 138 16 15536 0 0
intr 1146734384 997 0 0 1 1 0 0 0 1 0 0 0 0 0 1302607 0 0 262087 0 712704 0 0 0 <...省略若干数据...>
ctxt 89793364
btime 1366591448
processes 27283
procs_running 1
procs_blocked 0
softirq 1262462448 0 63122856 50789329 1074176388 225020 0 461213 9535581 76130 64075931

 

 

第一行的数据表示的是CPU中的使用情况。我们来解释一下这行数据各数值的含义

1)这些数值的单位都是jiffies,jiffies是内核中的一个全局变量,用来记录系统启动以来产生的节拍数,在Linux中,一个节拍大致可以理解为操作系统进程调度的最小时间片,不同的Linux内核这个值可能不同,通常在1ms到10ms之间

 

2)CPU 223447 240 4504182 410802165 59753 412 586209 0 0

  • user(223447) 从系统启动开始累积到当前时刻,处于用户态的运行时间,不包含 nice 值为负的进程。
  • nice(240) 从系统启动开始累积到当前时刻,nice 值为负的进程所占用的 CPU 时间。
  • system(4504182) 从系统启动开始累积到当前时刻,处于核心态的运行时间。
  • idle(410802165) 从系统启动开始累积到当前时刻,除 IO 等待时间以外的其他等待时间。
  • iowait(59753) 从系统启动开始累积到当前时刻,IO 等待时间。(since 2.5.41)
  • irq(412) 从系统启动开始累积到当前时刻,硬中断时间。(since 2.6.0-test4)
  • softirq(586209) 从系统启动开始累积到当前时刻,软中断时间。(since 2.6.0-test4)
  • stealstolen(0) Which is the time spent in other operating systems when running in a virtualized environment.(since 2.6.11)
  • guest(0) Which is the time spent running a virtual CPU for guest operating systems under the control of the Linux kernel.(since 2.6.24)

 

以上信息我们可以得到总的CPU活动时间为:

totalCPUTime = user + nice + system + idle + iowait + irq + softirq + stealstolen + guest

 

2.2、通过/proc/[PID]/stat 文件查看某一进程的CPU活动信息

2.2.1、存储进程新的文件目录

Linux系统贯彻"一切都是文件"的思想,所有的进程的运行状态也都可以通过读取文件来获取。/proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为内核与进程提供通信的接口。用户和应用程序可以通过/proc得到系统的信息,并且可以改变内核的某些参数。

在/proc/[PID]目录下的各个文件记录这个进程的各项运行指标。

 

2.2.2、查看进程运行的详细信息

通过查看/proc/[PID]/stat文件,可以查看进程运行的详细信息,其中包括CPU占用信息。比如

[root@rh ~]$ cat /proc/1/stat 1 (init) S 0 1 1 0 -1 4202752 3026 2635222 9 483 5 165 102346 3188016 20 0 1 0 1 19820544 384 18446744073709551615 1 1 0 0 0 0 0 4096 536962595 18446744073709551615 0 0 0 4 0 0 34 0 0

 

文件信息解释

  • pid=6873 进程(包括轻量级进程,即线程)号
  • comm=a.out 应用程序或命令的名字。
  • task_state=R 任务的状态,R:runnign, S:sleeping (TASK_INTERRUPTIBLE), D:disk sleep (TASK_UNINTERRUPTIBLE), T: stopped, T:tracing stop, Z:zombie, X:dead。
  • ppid=6723 父进程ID。
  • pgid=6873 线程组号。
  • sid=6723 该任务所在的会话组 ID。
  • tty_nr=34819(pts/3) 该任务的 tty 终端的设备号,INT(34817/256)= 主设备号,(34817-主设备号)= 次设备号。
  • tty_pgrp=6873 终端的进程组号,当前运行在该任务所在终端的前台任务(包括 shell 应用程序)的 PID。
  • task->flags=8388608 进程标志位,查看该任务的特性。
  • min_flt=77 该任务不需要从硬盘拷数据而发生的缺页(次缺页)的次数。
  • cmin_flt=0 累计的该任务的所有的 waited-for 进程曾经发生的次缺页的次数目。
  • maj_flt=0 该任务需要从硬盘拷数据而发生的缺页(主缺页)的次数。
  • cmaj_flt=0 累计的该任务的所有的 waited-for 进程曾经发生的主缺页的次数目。
  • utime=1587 该任务在用户态运行的时间,单位为 jiffies。
  • stime=1 该任务在核心态运行的时间,单位为 jiffies。
  • cutime=0 累计的该任务的所有的 waited-for 进程曾经在用户态运行的时间,单位为 jiffies。
  • cstime=0 累计的该任务的所有的 waited-for 进程曾经在核心态运行的时间,单位为 jiffies。
  • priority=25 任务的动态优先级。
  • nice=0 任务的静态优先级。
  • num_threads=3 该任务所在的线程组里线程的个数。
  • it_real_value=0 由于计时间隔导致的下一个 SIGALRM 发送进程的时延,以 jiffy 为单位。
  • start_time=5882654 该任务启动的时间,单位为 jiffies。
  • vsize=1409024(page) 该任务的虚拟地址空间大小。
  • rss=56(page) 该任务当前驻留物理地址空间的大小;Number of pages the process has in real memory,minu 3 for administrative purpose. 这些页可能用于代码,数据和栈。
  • rlim=4294967295(bytes) 该任务能驻留物理地址空间的最大值。
  • start_code=134512640 该任务在虚拟地址空间的代码段的起始地址。
  • end_code=134513720 该任务在虚拟地址空间的代码段的结束地址。
  • start_stack=3215579040 该任务在虚拟地址空间的栈的结束地址。
  • kstkesp=0 esp(32 位堆栈指针) 的当前值, 与在进程的内核堆栈页得到的一致。
  • kstkeip=2097798 指向将要执行的指令的指针, EIP(32 位指令指针)的当前值。
  • pendingsig=0 待处理信号的位图,记录发送给进程的普通信号。
  • block_sig=0 阻塞信号的位图。
  • sigign=0 忽略的信号的位图。
  • sigcatch=082985 被俘获的信号的位图。
  • wchan=0 如果该进程是睡眠状态,该值给出调度的调用点。
  • nswap 被 swapped 的页数,当前没用。
  • cnswap 所有子进程被 swapped 的页数的和,当前没用。
  • exit_signal=17 该进程结束时,向父进程所发送的信号。
  • task_cpu(task)=0 运行在哪个 CPU 上。
  • task_rt_priority=0 实时进程的相对优先级别。
  • task_policy=0 进程的调度策略,0=非实时进程,1=FIFO实时进程;2=RR实时进程

 

2.2.3、关于进程占用CPU的相关信息

  • pid 进程号。
  • utime 该任务在用户态运行的时间,单位为 jiffies。
  • stime 该任务在核心态运行的时间,单位为 jiffies。
  • cutime 累计的该任务的所有的 waited-for 进程曾经在用户态运行的时间,单位为 jiffies。
  • cstime 累计的该任务的所有的 waited-for 进程曾经在核心态运行的时间,单位为 jiffies。

该进程的CPU占用时间(该值包括其所有线程的CPU时间)

processCPUTime = utime + stime + cutime + cstime

 

2.4、单核情况下CPU使用率的计算

2.4.1 、基本思想

首先,通过读取/proc/stat文件获取总的CPU时间,读取/proc/[PID]/stat获取进程CPU时间,然后采样两个足够短的时间间隔的CPU快照与进程或线程快照来计算器CPU使用率

 

2.4.2、计算总CPU使用率totalCPUUse

1)采样两个足够短的时间间隔的CPU快照,即读取/proc/stat文件,获取两个时间点的下列数据:

  • CPUT1 (user1, nice1, system1, idle1, iowait1, irq1, softirq1, stealstolen1, guest1);
  • CPUT2 (user2, nice2, system2, idle2, iowait2, irq2, softirq2, stealstolen2, guest2);

 

2)计算总的CPU时间totalCPUTime

  • CPUTime1 = user1 + nice1 + system1 + idle1 + iowait1 + irq1 + softirq1 + stealstolen1 + guest1;
  • CPUTime2 = user2 + nice2 + system2 + idle2 + iowait2 + irq2 + softirq2 + stealstolen2 + guest2;

totalCPUTime = CPUTime2 - CPUTime1

 

3)计算CPU空闲时间idleCPUTime

idleCPUTime = idle2 - idle1

 

4)计算总的CPU使用率totalCPUUse

totalCPUUse = (totalCPUTime - idleCPUTime)/ totalCPUTime

 

2.4.3、计算某一个进程的CPU使用率processCPUUse

1)采样两个足够短的时间间隔的 CPU 快照和对应的进程快照,即读取 /proc/stat 文件,获取两个时间点的下列数据:

  • CPUT1 (user1, nice1, system1, idle1, iowait1, irq1, softirq1, stealstolen1, guest1);
  • CPUT2 (user2, nice2, system2, idle2, iowait2, irq2, softirq2, stealstolen2, guest2);

读取 /proc/[PID]/stat 文件,获取两个时间点的下列数据:

  • ProcessT1 (utime1, stime1, cutime1, cstime1);
  • ProcessT2 (utime2, stime2, cutime2, cstime2);

 

2)计算总的 CPU 时间 totalCPUTime 和进程时间 processTime:

  • CPUTime1 = user1 + nice1 + system1 + idle1 + iowait1 + irq1 + softirq1 + stealstolen1 + guest1;
  • CPUTime2 = user2 + nice2 + system2 + idle2 + iowait2 + irq2 + softirq2 + stealstolen2 + guest2;

totalCPUTime = CPUTime2 – CPUTime1;

  • processTime1 = utime1 + stime1 + cutime1 + cstime1;
  • processTime2 = utime2 + stime2 + cutime1 + cstime2;

processTime = processTime2 – processTime1;

 

3)计算该进程的 CPU 使用率 processCPUUse:

processCPUUse = processTime / totalCPUTime;

 

posted on 2020-04-04 15:22  gentleman_hai  阅读(4368)  评论(0编辑  收藏  举报

导航