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

no_renice
可以看到,此時%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

renice_5
可以發現,現在%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

renice_19
可以發現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

chrt
可以看到,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以下代表實時進程。

往期內容

Linux命令拾遺-入門篇
原來awk真是神器啊
Linux文本命令技巧(上)
Linux文本命令技巧(下)
字符編碼解惑


免責聲明!

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



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