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;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM