監控項 | 說明 | 監控值 |
Load_one |
One minute load average
每分鐘的系統平均負載 |
load_one=0.0 |
Load_five |
Five minute load average
每5分鐘的系統平均負載 |
load_five=0.0 |
Load_fifteen |
Fifteen minute load average
每15分鐘的系統平均負載 |
load_fifteen=0.0 |
mem_total |
Total amount of memory displayed in KBs
物理內存總量(KBs顯示) |
mem_total=2075288.0 |
mem_cached |
Amount of cached memory
緩存內存大小 |
mem_cached=470732.0 |
mem_free |
Amount of available memory
空閒內存大小 |
mem_free=1128860.0 |
mem_buffers |
Amount of buffered memory
內核緩存的內存總量 |
mem_buffers=353264.0 |
swap_total |
Total amount of swap space displayed in KBs
交換分區總量(KBs顯示) |
swap_total=8289532.0 |
swap_free |
Amount of available swap memory
空閒交換分區大小 |
swap_free=8289532.0 |
mem_shared |
Amount of shared memory
共享內存大小 |
mem_shared=0.0 |
proc_run |
Total number of running processes
運行的進程總數 |
proc_run=0.0 |
proc_total |
Total number of processes
進程總數 |
proc_total=65.0 |
cpu_idle |
Percentage of time that the CPU or CPUs were idle and the system did not have an outstanding disk I/O request 空閒CPU百分比 |
cpu_idle=99.6 |
cpu_aidle |
Percent of time since boot idle CPU
啓動的空閒CPU百分比 |
cpu_aidle=99.8 |
cpu_user |
Percentage of CPU utilization that occurred while executing at the user level
用戶空間佔用CPU百分比 |
cpu_user=0.2 |
cpu_nice |
Percentage of CPU utilization that occurred while executing at the user level with nice priority
用戶進程空間內改變過優先級的進程佔用CPU百分比 |
cpu_nice=0.0 |
cpu_system |
Percentage of CPU utilization that occurred while executing at the system level 內核空間佔用CPU百分比 |
cpu_system=0.1 |
cpu_num |
Total number of CPUs
CPU線程總數 |
cpu_num=2.0 |
cpu_speed |
CPU Speed in terms of MHz
CPU速度(MHz) |
cpu_speed=2993.0 |
cpu_wio |
Percentage of time that the CPU or CPUs were idle during which the system had an outstanding disk I/O request Cpu空閒時的最大I/O請求 |
cpu_wio=0.2 |
part_max_used | Maximum percent used for all partitions | part_max_used=21.2 |
disk_total |
Total available disk space
磁盤總大小 |
disk_total=133.991 |
disk_free |
Total free disk space
剩餘磁盤空間 |
disk_free=124.707 |
boottime |
The last time that the system was started
系統啓動時間 |
boottime=1285905983.0 |
pkts_in |
Packets in per second
每秒進來的包 |
pkts_in=10.5 |
pkts_out |
Packets out per second
每秒出去的包 |
pkts_out=2.85 |
bytes_in |
Number of bytes in per second
每秒進來字節數 |
bytes_in=769.35 |
bytes_out |
Number of bytes out per second
每秒出去字節數 |
bytes_out=3674.02 |
machine_type |
System architecture
系統版本(X86或64) |
machine_type=x86 |
os_name | 系統名字 | os_name=Linux |
os_release | 系統版本 | os_release=2.6.18-164.el5PAE |
gexec | gexec available | gexec=OFF |
disk_free_rootfs | Disk space available on | WARN: ‘ disk_free_rootfs |
獲取內核上報的時間戳是通過進程輪詢的方式,但是發現該進程在實際運行中CPU佔用率很高,其中就是一個死循環在讀取設備文件,本以爲是由於讀系統調用太頻繁的原因。
於是又寫一個測試程序,其中僅僅是個空循環。結果發現該程序的CPU佔用率居然在90%多!
針對這個問題我有2個疑問,對這些疑問的理解也記錄在此,與大家分享。
1 linux系統是時間片調度算法,微觀上所有可運行進程都是串行,不管進程中作何操作,該進程的時間片一到就切換到下一進程,那爲什麼一個空循環進程CPU佔用率還這麼高。
要徹底搞明白這個問題,需要弄清楚2個問題
(1)linux進程的幾種狀態以及其切換關係。
(2)CPU佔用率如何計算出來的。
linux進程的幾種狀態以及其切換關係在《深入學習linux內核》中有詳細介紹,這裏簡單說下。
進程是一個動態的實體,所以他是有生命的。從創建到消亡,是一個進程的整個生命週期。在這個週期中,進程可能會經歷各種不同的狀態。一般來說,所有進程都要經歷以下的3個狀態:
就緒態。指進程已經獲得所有所需的其他資源,正在申請處理處理器資源,準備開始執行。這種情況下,稱進程處於就緒態。
阻塞態。指進程因爲需要等待所需資源而放棄處理器(如系統調用阻塞或者sleep),或者進程本不擁有處理器,且其他資源也沒有滿足,從而即使得到處理器也不能開始運行。這種情況下,進程處於阻塞態。阻塞狀態也稱休眠狀態或者等待狀態。
運行態。進程得到了處理器,並不需要等待其他任何資源,正在執行的狀態,稱之爲運行態。只有在運行態時,進程纔可以使用所申請到的資源。在所有進程中同一時刻僅有一個進程處於運行態。
在Linux系統中,將各種狀態進行了重新組織,由此得到了Linux進程的幾個狀態:
RUNNING:正在運行或者在就緒隊列中等待運行的進程。也就是上面提到的運行態和就緒態進程的綜合。一個進程處於RUNNING狀態,並不代表他一定在被執行。由於在多任務系統中,各個就緒進程需要併發執行,所以在某個特定時刻,這些處於RUNNING狀態的進程之中,只有一個能得到處理器,而其他進程必須在一個就緒隊列中等待。即使是在多處理器的系統中,Linux也只能同時讓一個處理器執行任務。
UNINTERRUPTABLE:不可中斷阻塞狀態。處於這種狀態的進程正在等待隊列中,當資源有效時,可由操作系統進行喚醒,否則,將一直處於等待狀態。
INTERRUPTABLE:可中斷阻塞狀態。與不可中斷阻塞狀態一樣,處於這種狀態的進程在等待隊列中,當資源有效時,可以有操作系統進行喚醒。與不可中斷阻塞狀態有所區別的是,處於此狀態中的進程亦可被其他進程的信號喚醒。
STOPPED:掛起狀態。進程被暫停,需要通過其它進程的信號才能被喚醒。導致這種狀態的原因有兩種。其一是受到相關信號(SIGSTOP,SIGSTP,SIGTTIN或SIGTTOU)的反應。其二是受到父進程ptrace調用的控制,而暫時將處理器交給控制進程。
ZOMBIE:殭屍狀態。表示進程結束但尚未消亡的一種狀態。此時進程已經結束運行並釋放掉大部分資源,但尚未釋放進程控制塊。
使用PS命令查看進程時可以看到,“S”進程是指處於阻塞狀態,“R”進程處於就緒或運行狀態。
進一步理解,linux 進行進程調度時是對就緒隊列中的進程進行時間片的分配。而阻塞狀態和掛起狀態的進程都處在阻塞隊列中,只有喚醒後才能加入就緒隊列中等待內核的調度。
再來看CPU佔有率是如何計算出來的。
首先需要明白的是隻要設備上電CPU就不會閒着,總會有某個進程佔用CPU運行,linux內核啓動最終會啓動cpu_idle進程,在該進程中會死循環調用schedule函數進行調度,即使就緒隊列中沒有進程可以調度,也就是說沒有進程時RUNNING狀態,CPU也會一直在cpu_idle中死循環。而我們常說的CPU被佔用其實是指就緒隊列中有進程被調度使用CPU,CPU佔有率也就是該進程使用CPU的的一個百分比。
搞明白了以上兩點,再反過來看我們的問題。爲什麼空循環進程CPU佔用率高呢。
可以想象,空循環進程中雖然沒做任何事情,卻沒有阻塞條件(如sleep),進程一直處於RUNNING狀態,也就是說即使該進程時間片到了被切換,該進程還是處於就緒隊列,等待下次調度。
linux內核的調度算法是很複雜的,根據UTLK介紹,關鍵因素在於時間片的分配和優先級的計算,優先級越高的進程時間片分配越長。
這裏咱們去繁就簡,假設linux內核調度算法僅僅是等時時間片調度,也就是說1s內所有運行進程時間片是相等的,其實就是將1s時間平分給就緒隊列中的所有進程。所以問題的關鍵就是就緒隊列中有多少個進程來平分這個時間了。
對我的設備中ps命令查看進程狀態,發現只有空循環進程是RUNNING狀態的。
但是由於運行top命令時top也是一個RUNNING進程,因此這時的linux內核僅僅對這2個進程進行來回調度,當然空循環進程的CPU佔用率高了!
2 既然CPU一直被佔用,CPU負載高低如何解釋,空循環進程對系統有什麼影響。
想明白空循環進程問題後我就對CPU負載高低產生了疑問,既然CPU一直有進程佔用,也就是說CPU其實是一直滿載的,爲什麼還有負載高低這一說。
我的理解是這樣的,對於CPU來說,它一直是按照固定的頻率取指令運行,沒有負載高低之說,我們所說的負載高低其實是人感官的說法,比如top查看發現CPU佔用率高,系統主要應用進程(如sh)反應慢,我們就說負載高。
打個形象點的比方,CPU可以比喻爲家庭機器人,可以進行做飯 洗衣服 掃地,機器人做這些工作的速度是不變的。做飯10分鐘完成,但是如果要求它做飯 洗衣服 掃地同時進行,站在機器人的角度來說,沒有差別,速度是一樣的。但是從我們的角度來看我們的主要應用-做飯,就發現它做飯慢了,我們就認爲機器人是不是負載太高啦。
因此空循環對系統的影響也就好理解了,就會導致就緒隊列中無意義的進程多了,但一個空循環進程影響不明顯。
就緒隊列中本來只有2個進程,主應用進程在1s內可以運行0.5s,但是如果有20個進程,則只可以運行0.05s,進程的執行響應效率也就下來了。
這裏可以做一個簡單的試驗,在我的設備系統中啓動幾十個空循環進程,發現系統控制檯反應都慢了,這就驗證了以上說法。