本篇內(nèi)容主要講解“如何理解Linux之進程優(yōu)先級PR和NI”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“如何理解Linux之進程優(yōu)先級PR和NI”吧!
創(chuàng)新互聯(lián):于2013年創(chuàng)立為各行業(yè)開拓出企業(yè)自己的“網(wǎng)站建設(shè)”服務(wù),為數(shù)千家公司企業(yè)提供了專業(yè)的網(wǎng)站設(shè)計制作、成都網(wǎng)站制作、網(wǎng)頁設(shè)計和網(wǎng)站推廣服務(wù), 按需求定制開發(fā)由設(shè)計師親自精心設(shè)計,設(shè)計的效果完全按照客戶的要求,并適當(dāng)?shù)奶岢龊侠淼慕ㄗh,擁有的視覺效果,策劃師分析客戶的同行競爭對手,根據(jù)客戶的實際情況給出合理的網(wǎng)站構(gòu)架,制作客戶同行業(yè)具有領(lǐng)先地位的。
JDK中線程有優(yōu)先級,0-10,10表示優(yōu)先級最大,而在Linux中則值最小表示優(yōu)先級最高,優(yōu)先級高的占用CPU的時間多。
Linux中有PR和NI,在top命令的結(jié)果中就可以看到,如下圖1是top的結(jié)果,可以看到NI和PR的列值:
圖1
先來搞清楚PR(priority)和NI(nice)值的區(qū)別
這是一個反應(yīng)進程優(yōu)先級狀態(tài)的值,范圍在-20到19,即總共有40個值,值最小,優(yōu)先級最高,默認值是0
nice值越低的進程搶占CPU的能力越強,而nice值越高的進程搶占CPU的能力越弱
在原來O1調(diào)度的Linux上,nice值也叫靜態(tài)優(yōu)先級,一旦設(shè)置了,除非手動renice修改值,否則不會改變;在priority值在O1調(diào)度的Linux上,值是會變的,所以也叫動態(tài)優(yōu)先級。
在linux上,renice 10 pid,這樣就可以將pid的那個進程的優(yōu)先級設(shè)置為10,renice設(shè)置值的時候只能設(shè)置為值更大的值,比如之前的值是5,之后的值設(shè)置為10是可以的,但是設(shè)置為-10是不可以的,會報沒有權(quán)限的錯誤,除非使用root用戶。
實時操作系統(tǒng)需要保證相關(guān)的實時進程在較短的時間內(nèi)響應(yīng),不會有較長的延時,并且要求最小的中斷延時和進程切換延時。對于這樣的需求,一般的進程調(diào)度算法,無論是O1還是CFS都是無法滿足的,所以內(nèi)核在設(shè)計的時候,將實時進程單獨映射了100個優(yōu)先級,這些優(yōu)先級都要高于正常進程的優(yōu)先級(nice值),而實時進程的調(diào)度算法也不同,它們采用更簡單的調(diào)度算法來減少調(diào)度開銷。
由于實時進程,無論是O1還是CFS調(diào)度,都滿足不了,所以給它們分配0-100的值優(yōu)先級,使用簡單的調(diào)度算法,來減少開銷。
實時進程和非實時進程的區(qū)分是通過優(yōu)先級來區(qū)分的,0-99的都是實時進程,而100-139的都是非實時進程,NICE的-20~19對應(yīng)著100~139,如果PR列中看到的是'rt',那么說明這個任務(wù)/進程是realtime進程,即實時進程,有時候會看到PR的值不是數(shù)值,而是rt的。
如下List-1中所示,policy options部分,系統(tǒng)給進程5種調(diào)度策略,這5中調(diào)度策略是給倆中進程使用的,實時進程:SCHED_FIFO、SCHED_RR,而對于非實時進程則是:SCHED_OTHER、SCHED_OTHER、SCHED_IDLE。
List-1
mjduan@dmj:/mnt/sdb1/doc/minedoc$ chrt --help Show or change the real-time scheduling attributes of a process. Set policy: chrt [options][ ...] chrt [options] --pid Get policy: chrt [options] -p Policy options: -b, --batch set policy to SCHED_BATCH -d, --deadline set policy to SCHED_DEADLINE -f, --fifo set policy to SCHED_FIFO -i, --idle set policy to SCHED_IDLE -o, --other set policy to SCHED_OTHER -r, --rr set policy to SCHED_RR (default) Scheduling options: -R, --reset-on-fork set SCHED_RESET_ON_FORK for FIFO or RR -T, --sched-runtime runtime parameter for DEADLINE -P, --sched-period period parameter for DEADLINE -D, --sched-deadline deadline parameter for DEADLINE Other options: -a, --all-tasks operate on all the tasks (threads) for a given pid -m, --max show min and max valid priorities -p, --pid operate on existing given pid -v, --verbose display status information -h, --help display this help -V, --version display version For more details see chrt(1).
系統(tǒng)的整體調(diào)度策略:
如果系統(tǒng)中存在要執(zhí)行的實時進程,那么執(zhí)行實時進程
直到實時進程退出或者主動讓出CPU時,才會調(diào)度執(zhí)行非實時進程
sched_fifo: 是實時進程的調(diào)度策略之一,使用FIFO的策略,在優(yōu)先級一樣的情況下,誰先進入隊列那么那個先被調(diào)度
sched_rr: 是實時進程調(diào)度策略之一,使用時間分片的策略,默認是100ms,這種策略簡單,適合實時進程延時小的特點
Linux上更麻煩的是非實時調(diào)度策略,linux上很多進程都是非實時進程,它們的主要調(diào)度算法是O1和CFS調(diào)度策略
是2.6內(nèi)核版本引入的,到2.6.63就被替換為CFS了
命名為O1是因為它算法的時間復(fù)雜度是O1,使用時間分片思路來,將cpu的時間分為一小段一小段,每個進程占用一段時間分片,對于多核的來說,對每個cpu進行這樣時間分片即可。優(yōu)先級是怎么處理的呢:優(yōu)先級高的時間分片占用多,反之占用少
O1對多核、多CPU支持的不好,性能不好,此外linux內(nèi)核還要加上cgroup的功能,所以被替換為了CFS,Linux在2.6.23之后開始啟用CFS作為對一般優(yōu)先級(SCHED_OTHER)進程調(diào)度方法
CFS調(diào)度策略會收集虛擬時間,然后構(gòu)建紅黑樹red-block tree,虛擬時間就是紅黑樹的key,所以虛擬時間越短的會在紅黑樹的最左邊,查詢的時間復(fù)雜度是Log(N)。
大致是這樣的,會根據(jù)當(dāng)前進程的優(yōu)先級和執(zhí)行時間,來生成一個虛擬時間,對每個進程都是如此,最后構(gòu)建紅黑樹,紅黑樹中左邊的進程表示虛擬時間值小,表示大部分時候在占用cpu,而右邊的進程表示虛擬時間大,當(dāng)一個虛擬時間小的進程在占用cpu時,如果此時一個虛擬時間大的進程變得可運行,那么這個虛擬時間大的就會搶占cpu,即系統(tǒng)總是調(diào)度虛擬時間比較小的進程
圖2
多核cpu情況下,CFS是怎么優(yōu)化性能的,每個cpu會維護一個調(diào)度隊列,避免使用全局隊列而出現(xiàn)爭搶的鎖問題,但是每個cpu一個隊列之后,就有可能出現(xiàn)負載不均衡,所以系統(tǒng)需要定期對各個cpu隊列進行平衡
如下List-2中,使用chrt命令查看進程的優(yōu)先級是0,調(diào)度算法是CFS
List-2
mjduan@dmj:/mnt/sdb1/doc/minedoc$ jps 26960 Main 12642 Jps 27090 Main 890 RemoteJdbcServer 31980 Launcher mjduan@dmj:/mnt/sdb1/doc/minedoc$ chrt -p 27090 pid 27090's current scheduling policy: SCHED_OTHER pid 27090's current scheduling priority: 0 mjduan@dmj:/mnt/sdb1/doc/minedoc$ chrt -p 890 pid 890's current scheduling policy: SCHED_OTHER pid 890's current scheduling priority: 0
如果需要調(diào)度的進程個數(shù)為n,那么平均每個進程占用的CPU時間為sched_latency_ns/n。顯然,每個進程實際占用的CPU時間會因為n的增大而減小。但是實現(xiàn)上不可能讓它無限的變小,所以sched_min_granularity_ns的值也限定了每個進程可以獲得的執(zhí)行時間周期的最小值
List-3
mjduan@dmj:/mnt/sdb1/doc/minedoc$ cat /proc/sys/kernel/sched_latency_ns 3000000 mjduan@dmj:/mnt/sdb1/doc/minedoc$ cat /proc/sys/kernel/sched_min_granularity_ns 300000
對于普通進程而言,PR=nice+20,所以默認情況下,創(chuàng)建的進程nice值是0,而PR值是20,比如默認的情況下java應(yīng)用的PR就是20.
對于rt進程,即實時進程,PR=-1-用戶視角,所以有時候看到PR值是-51的進程,那么它實際對應(yīng)的優(yōu)先級是50,有時候看到PR的值是rt而不是數(shù)值,這種對應(yīng)的優(yōu)先級是99
到此,相信大家對“如何理解Linux之進程優(yōu)先級PR和NI”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!