Linux命令拾遺-top中的%nice是啥
原創:打碼日記(微信公眾號ID:codelogs),歡迎分享,轉載請保留出處。
簡介
這是Linux命令拾遺系列的第八篇,本篇主要介紹top命令中nice%這個指標的含義以及程序優先順序相關內容。
本系列文章索引
Linux命令拾遺-入門篇
Linux命令拾遺-文字處理篇
Linux命令拾遺-軟體資源觀測
Linux命令拾遺-硬體資源觀測
Linux命令拾遺-剖析工具
Linux命令拾遺-動態追蹤工具
Linux命令拾遺-理解系統負載
在各種檢視CPU使用率的工具中(如top),一般都有us%、sy%、ni%等,us%與sy%含義是比較容易理解的,一個是使用者態CPU使用率,一個是核心態CPU使用率。
但ni%就比較晦澀難懂了,它代表被調整過nice值的程序佔用的CPU使用率,很難理解對不對,來看看下面的例子。
調整程序nice值
首先,我們使用stress命令起2個程序,對CPU製造一些壓力,如下:
# 起2個吃CPU的後臺程序
$ stress -c 2 &
# 檢視兩個stress程序,程序號為194022、194022
$ pstree -Tp $$
bash(193921)─┬─pstree(194101)
└─stress(194017)─┬─stress(194022)
└─stress(194023)
由於我機器是多核的,作業系統會將兩個stress程序排程到兩個核上,為了達到效果,我們將這2個程序繫結到1號核上執行,如下:
# 繫結2個stress程序到CPU的1號核上
$ taskset -pc 1 194022
$ taskset -pc 1 194023
# 然後使用top檢視,如下圖
$ top
可以看到,此時%Cpu1是佔滿的100%,兩個stress程序各佔50%,這很好理解,兩個同樣吃CPU程序跑在一個核上,大家各分一半嘛!
這裡需要注意一下程序的PR與NI列,這兩個都代表了程序的優先順序,PR是核心排程時使用的優先順序(priority),預設20,值越大優先順序越低,而NI是開放給使用者調整的優先順序(nice),預設0,nice值越大,則程序會表現得越謙讓(nice),先讓別的程序獲得CPU,表現為優先順序越低。
如下,我們通過renice命令調整194023程序的nice值為5,以降低它的優先順序:
$ renice -n 5 -p 194023
$ top
可以發現,現在%Cpu1的us是75.7,ni是24.3,沒被調整nice的程序194022的%CPU是75.1,而調整了的程序194023的%CPU是24.6,同時NI列從0變成了5,PR列從20變成了25,可以發現%ni的值24.3幾乎等於被調整過nice值程序的CPU使用率,即24.6。
再看看我開頭說的ni%的定義,ni%代表被調整過nice值的程序佔用的CPU使用率
,現在感覺這句話是不是再清楚不過了,被調整了nice值的程序,會從us%中分離出來單獨顯示,這樣當一批非常吃CPU的程序被調整nice值後,調整的人就能非常清楚的知道,這些程序現在佔用多少CPU了。
如下,再通過renice命令呼叫194023程序的nice值為19,這是nice值能設定的最大值:
$ renice -n 19 -p 194023
$ top
可以發現194023這個程序CPU使用率更低了,且%Cpu1的ni也更低了,並且NI變成了19,PR變成了39。
PR與NI
上面可以看到,PR與NI好像滿足這樣一種等式關係:PR = 20 + NI
,那麼為什麼Linux要設計這兩套優化級呢?
其實,在程序執行的過程中,就算你調整了程序NI值導致PR變化,PR還是可以再次由CPU排程器根據需要動態調整的,在這種情況下,上面的公式就不成立了。並且,在核心程式碼裡,PR才是CPU排程器真正使用的優化級,而NI只是開放給使用者修改的。
另外,NI值是給普通程序使用的,範圍是[-20 ~ 19]
共39個級別,對應PR就是[0 ~ 39]
。
而PR的取值範圍可以是[-100 ~ 39]
共139個級別,其中[-100, -1]
是給實時程序用的。
所以在Linux中PR大於0是普通程序,小於0是實時程序。
注:在top中會看到 PR = rt 的程序,這個rt等同於-100
可以發現,對於普通程序,不管使用者怎麼調整NI值,程序的PR都不會低於0,也就是保證所有實時程序的優先順序,都要大於普通程序,像Linux中的一些核心程序就是實時程序(如:migration/0),必須保證他們被優先執行。
如下,在Linux中,可以通過chrt命令檢視核心支援的實時程序排程策略:
$ chrt -m
SCHED_OTHER min/max priority : 0/0
SCHED_FIFO min/max priority : 1/99
SCHED_RR min/max priority : 1/99
SCHED_BATCH min/max priority : 0/0
SCHED_IDLE min/max priority : 0/0
SCHED_DEADLINE min/max priority : 0/0
是的,你會發現SCHED_FIFO/SCHED_RR策略都有[1,99]
共99個實時優先順序(real_time_priority)可用,它和PR的關係是:PR = -1 - real_time_priority
。
如下,之前通過增大NI值而降低了優先順序的194023程序,我再把它修改為實時程序:
# 設定194023程序為實時程序,排程策略為SCHED_RR,實時優先順序為10,PR = -1 -10 = -11
$ sudo chrt --rr --pid 10 194023
# 檢視實時優先順序
$ chrt -p 194023
pid 194023's current scheduling policy: SCHED_RR
pid 194023's current scheduling priority: 10
# 再看CPU使用率
$ top
可以看到,194023被調整為實時程序後,把CPU佔滿了,沒有給同核心執行的普通程序194022留下任何CPU時間。
所以實時程序的排程是搶佔式的,只要其不結束,低優先順序程序完全沒有機會使用CPU,而對於普通程序而言,多少會留一點CPU時間給其它低優先順序的普通程序使用的。
另外,使用ps -l
也可以檢視程序的PR與NI,如下:
$ ps -lp 194022 194023
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
1 R 0 194022 194017 97 80 0 - 964 - ? 1943:32 stress -c 2
1 R 0 194023 194017 2 49 - - 964 - ? 52:08 stress -c 2
看PRI這一列,可以發現,194022在top中是20,在ps中是80,而194023在top中是-11,在ps中是49,它們都相差60。
是的,他們含義是一致的,只是顯示的基準值不同而已,top中0以下代表實時程序,而ps -l
中60以下代表實時程序。