歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

Linux的進程優先級NI和PR有什麼區別?

為什麼要有進程優先級?

這似乎不用過多的解釋,畢竟自從多任務操作系統誕生以來,進程執行占用cpu的能力就是一個必須要可以人為控制的事情。因為有的進程相對重要,而有的進程則沒那麼重要。

進程優先級起作用的方式從發明以來基本沒有什麼變化,無論是只有一個cpu的時代,還是多核cpu時代,都是通過控制進程占用cpu時間的長短來實現的。

就是說在同一個調度周期中,優先級高的進程占用的時間長些,而優先級低的進程占用的短些。

請大家真的不要混淆了系統中的這兩個概念:nice(NI)和priority(PR),他們有著千絲萬縷的關系,但對於當前的Linux系統來說,它們並不是同一個概念。

我們看這個命令:

linux

大家是否真的明白其中PRI列NI列的具體含義有什麼區別?

同樣的,如果是top命令:

linux

大家是否搞清楚了這其中PR值NI值的差別?如果沒有,那麼我們可以首先搞清楚什麼是nice值。

什麼是NICE值?

NICE值應該是熟悉Linux/UNIX的人很了解的概念了,它是反應一個進程“優先級”狀態的值,其取值范圍是-20至19,一共40個級別。

這個值越小,表示進程”優先級”越高,而值越大“優先級”越低。

例如,我們可以通過NICE命令來對一個將要執行的bash命令進行NICE值設置,方法是:

[root@zorrozou-pc0 zorro]# nice -n 10 bash

這樣我就又打開了一個bash,並且其nice值設置為10,而默認情況下,進程的優先級應該是從父進程繼承來的,這個值一般是0。

我們可以通過nice命令直接查看到當前shell的nice值:

[root@zorrozou-pc0 zorro]# nice 10

對比一下正常情況:

[root@zorrozou-pc0 zorro]# exit

退出當前nice值為10的bash,打開一個正常的bash,我們查看下其 Nice值:

[root@zorrozou-pc0 zorro]# bash

[root@zorrozou-pc0 zorro]# nice 0

另外,使用renice命令可以對一個正在運行的進程進行nice值的調整,我們也可以使用比如top、ps等命令查看進程的nice值,具體方法我就不多說了,大家可以參閱相關man page。

需要大家注意的是,我在這裡都在使用nice值這一稱謂,而非優先級(priority)這個說法。

nice值雖然不是priority,但是它確實可以影響進程的優先級

在英語中,如果我們形容一個人nice,那一般說明這個人的人緣比較好。什麼樣的人人緣好?往往是謙讓、有禮貌的人。

比如,你跟一個nice的人一起去吃午飯,點了兩個一樣的飯,先上了一份後,nice的那位一般都會說:“你先吃你先吃!”,這就是人緣好,這人nice!但是如果另一份上的很晚,那麼這位nice的人就要餓著了。

這說明什麼?

越nice的人搶占資源的能力就越差,而越不nice的人搶占能力就越強。這就是nice值大小的含義,nice值越低,說明進程越不nice,搶占cpu的能力就越強,優先級就越高(作者這個解釋太形象了,小編忍不住要手動點贊!!)。

在原來使用O1調度的Linux上,我們還會把nice值叫做靜態優先級,這也基本符合nice值的特點,就是當nice值設定好了之後,除非我們用renice去改它,否則它是不變的。

而priority的值在之前內核的O1調度器上表現是會變化的,所以也叫做動態優先級。

什麼是優先級和實時進程?

我們再來看看什麼是priority值,就是ps命令中看到的PRI值或者top命令中看到的PR值。

本文為了區分這些概念,以後:

統一用nice值表示NI值,或者叫做靜態優先級,也就是用nice和renice命令來調整的優先級;

而實用priority值表示PRI和PR值,或者叫動態優先級。

我們也統一將“優先級”這個詞的概念規定為表示priority值的意思。

在內核中,進程優先級的取值范圍是通過一個宏定義的,這個宏的名稱是MAX_PRIO,它的值為140。

而這個值又是由另外兩個值相加組成的,一個是代表nice值取值范圍的NICE_WIDTH宏,另一個是代表實時進程(realtime)優先級范圍的MAX_RT_PRIO宏。

說白了就是,Linux實際上實現了140個優先級范圍,取值范圍是從0-139,這個值越小,優先級越高。nice值的-20到19,映射到實際的優先級范圍是100-139。

新產生進程的默認優先級被定義為:

#define DEFAULT_PRIO   (MAX_RT_PRIO + NICE_WIDTH / 2)

實際上對應的就是nice值的0。

正常情況下,任何一個進程的優先級都是這個值,即使我們通過nice和renice命令調整了進程的優先級,它的取值范圍也不會超出100-139的范圍,除非這個進程是一個實時進程,那麼它的優先級取值才會變成0-99這個范圍中的一個。

這裡隱含了一個信息,就是說當前的Linux是一種已經支持實時進程的操作系統。

什麼是實時操作系統?

我們就不再這裡詳細解釋其含義以及在工業領域的應用了,有興趣的可以參考一下實時操作系統的維基百科。

簡單來說,實時操作系統需要保證相關的實時進程在較短的時間內響應,不會有較長的延時,並且要求最小的中斷延時和進程切換延時。

對於這樣的需求,一般的進程調度算法,無論是O1還是CFS都是無法滿足的,所以內核在設計的時候,將實時進程單獨映射了100個優先級,這些優先級都要高於正常進程的優先級(nice值),而實時進程的調度算法也不同,它們采用更簡單的調度算法來減少調度開銷。

總的來說,Linux系統中運行的進程可以分成兩類:

  • 實時進程
  • 非實時進程

它們的主要區別就是通過優先級來區分的。

所有優先級值在0-99范圍內的,都是實時進程,所以這個優先級范圍也可以叫做實時進程優先級,而100-139范圍內的是非實時進程

在系統中可以使用chrt命令來查看、設置一個進程的實時優先級狀態。我們可以先來看一下chrt命令的使用:

linux

我們先來關注顯示出的Policy options部分,會發現系統給各種進程提供了5種調度策略。

但是這裡並沒有說明的是,這五種調度策略是分別給兩種進程用的,對於實時進程可以用的調度策略是:SCHED_FIFO、SCHED_RR,而對於非實時進程則是:SCHED_OTHER、SCHED_OTHER、SCHED_IDLE。

系統的整體優先級策略是:

  • 如果系統中存在需要執行的實時進程,則優先執行實時進程;
  • 直到實時進程退出或者主動讓出CPU時,才會調度執行非實時進程。

實時進程可以指定的優先級范圍為1-99,將一個要執行的程序以實時方式執行的方法為:

[root@zorrozou-pc0 zorro]# chrt 10 bash

[root@zorrozou-pc0 zorro]# chrt -p $$

pid 14840's current scheduling policy: SCHED_RR

pid 14840's current scheduling priority: 10

Copyright © Linux教程網 All Rights Reserved