Linux的top或者ps均可以查看進程的cpu利用率,那爲何還須要瞭解這個細節呢。編寫這篇文章呢有以下三個緣由:php
* 但願在腳本中,可以以過」非阻塞」的方式獲取進程cpu利用率 * ps沒法得到進程當前時刻的CPU利用率;top則須要至少1秒才能得到進程當前的利用率 * * 好奇
在Linux的/proc文件系統,能夠看到自啓動時候開始,全部CPU消耗的時間片;對於個進程,也能夠看到進程消耗的時間片。這是一個累計值,能夠"非阻塞"的輸出。得到必定時間間隔的兩次統計就能夠計算出這段時間內的進程CPU利用率。linux
因此,是否存在一種簡單的,非阻塞的方式得到進程的CPU利用率? 答案是:「沒有」。這裏給出來一個有趣的比喻:"這就像有人給你一張照片,要你回答照片中車子的速度同樣"git
這 個概念在計算中並不重要,可是瞭解一下仍是有益的。在/proc/[pid/]stat中咱們能夠看到系通通計的CPU時間消耗,這裏都統一使用1 /USER_HZ爲一個時間片(man proc),多數狀況下USER_HZ都是取值100,因此這裏的一個時間片就是10ms。能夠經過系統調用sysconf(_SC_CLK_TCK)來 得到準確USER_HZ的取值。shell
例如:express
# cat /proc/stat|grep "cpu "cpu 77918485 720414 61184026 19052884316 12152363 1386 1476742 0 0
每 一列對應的CPU消耗含義是(man proc):用戶態(user)、低優先級用戶態(nice)、系統(sys)、閒置、IOWAIT(內核2.5.41+)、中斷(since 2.6.0+)、軟終端(since 2.6.0+)、steal(虛擬環境中其餘OS消耗2.6.11+)、guest(爲訪客OS運行虛擬CPU消耗2.6.24)tcp
對應以下:ide
# cat /proc/stat|grep "cpu " |usr |nice |sys |idle |iowait |irq |softirq |steal |guestcpu |77918485 |720414 |61184026 |19052884316 |12152363 |1386 |1476742 |0 |0
因此,計算CPU總消耗可使用以下shell命令:工具
cat /proc/stat|grep "cpu "|awk '{for(i=2;i<=NF;i++)j+=$i;print "cpu_total_slice " j;}'cpu_total_slice 19208187744
不少地方看到都只是統計前面四列或者五列,這是不完整的;不過,由於一般前4、五列是CPU的主要消耗,因此這樣如此計算也一般是準確的。例如,上例中,前面五列的消耗是CPU消耗的99.99%。idea
(tips:這裏的時間片和CPU時鐘中斷的jiffy不是一個概念,一個是內核態的,一個用戶態的)spa
在 proc文件系統中,能夠經過/proc/[pid]/stat得到進程消耗的時間片,輸出的第1四、1五、1六、17列分別對應進程用戶態CPU消耗、 內核態的消耗、用戶態等待子進程的消耗、內核態等待子進程的消耗(man proc)。因此進程的CPU消耗可使用以下命令:
cat /proc/9583/stat|awk '{print "cpu_process_total_slice " $14+$15+$16+$17}'cpu_process_total_slice 1068099
tips:從這裏能夠看到,Linux並無進程級別的iowait統計,若是想知道系統的iowait是哪一個進程致使,則還須要一些其餘的工具輔助。
從 這裏也看到,是沒有某個時刻CPU利用率的說法的,也就無法得到某個時刻的CPU利用率。這就像物理中的"速度"的概念,沒有某一時刻速度的概念,速度一 定是一個時間段以內的。那麼要"非阻塞"計算某個進程CPU利用率,則須要取兩次事件間隔進行計算,這兩次事件間隔的操做能夠是非阻塞的。計算辦法以下:
* 時刻A,計算操做系統總CPU時間片消耗total_cpu_slice_A;計算進程總CPU時間片消耗;total_process_slice_A* 時刻B,計算操做系統總CPU時間片消耗total_cpu_slice_B;計算進程總CPU時間片消耗;total_process_slice_B
B時刻就能夠"非阻塞"的計算這段時間進程的CPU利用率了:
100%*(total_process_slice_B-total_process_slice_A)/(total_cpu_slice_B-total_cpu_slice_A)
man ps...... CPU usage is currently expressed as the percentage of time spent running during the entire lifetime of a process. This is not ideal, and it does not conform to the standards that ps otherwise conforms to. CPU usage is unlikely to add up to exactly 100%.......
能夠看到,ps命令%CPU顯示的是進程自啓動時刻起,直至當前的總平均CPU利用率。
* man proc / man ps
* Accurately Calculating CPU Utilization in Linux using /proc/stat@stackoverflow
* account_process_tick@Linux Kernel