總述
為便于快速了解和復習,本節先給出結論性的大致概述,后面再詳細介紹相關內容,關于行程優先級和調度策略的大致資訊如下,
概念
行程優先級值越小,優先級越大,
行程優先級是PRI值不是Nice值,但是Nice值會影響優先級,
三類調度策略:RR調度和FIFO調度的行程屬于實時行程,以分時調度(OTHER)的行程是非實時行程
實時行程優先級高于普通行程,實時行程使用靜態優先級調度、非實時行程使用動態優先級調度,非實時行程動態優先級通過nice調整、可能受bonus影響,
方法
命令列/shell腳本中,可以通過 ps, top, chrt 來查看和修改調度和優先級屬性,
代碼中,通過系統呼叫 sched_setscheduler() 設定行程調度和優先級屬性(需要包含 sched.h),
代碼中,通過庫函式 pthread_attr_setschedpolicy() 設定執行緒調度和優先級屬性(需要包含 pthread.h),
原理
一般子行程會繼承父行程的調度策略,在Linux 2.6.32之后,可以使用 SCHED_RESET_ON_FORK 按位與引數的方式呼叫 sched_setscheduler(), 使用之后效果是:如果呼叫行程使用 SCHED_FIFO 或 SCHED_RR 調度策略,使用 SCHED_RESET_ON_FORK 后fork創建的子行程創建時將會自動重置為 SCHED_OTHER 調度策略;如果呼叫行程使用負值nice,那么使用 SCHED_RESET_ON_FORK 后fork創建的子行程創建時將會自動將其nice重置為0, 這個標記激活時只有當行程具有 CAP_SYS_NICE 標記時才能被重置,而這個 CAP_SYS_NICE 標記在使用fork()創建子行程后,在子行程中被禁止,
【文章福利】需要C/C++ Linux服務器架構師學習資料加群812855908(資料包括C/C++,Linux,golang技術,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK,ffmpeg等)

行程優先級概念
行程優先級值越小,優先級越大,
linux下的行程調度優先級是從 -20 到 19 ,一共 40 個級別,數字越大,表示行程的優先級越低,默認時候,行程的優先級是0,
如果不是 root 權限,則侄只能降調度優先級而不能提高,即使是自己用戶的行程,自己把它調高了后,優先級也不能再被調會原來的值了,除非使用 root 用戶來調回去,
系統重啟后,對行程優先級的調整全部失效,所有行程的調度回到默認的初始級別,
行程優先級是 PRI 值不是 Nice 值,但是 Nice 值會影響優先級
PRI 也還是比較好理解的,即行程的優先級,或者通俗點說就是程式被 CPU 執行的先后順序,此值越小行程的優先級別越高,那 NI 呢?就是我們所要說的 nice 值了,其表示行程可被執行的優先級的修正數值,如前面所說, PRI 值越小越快被執行,那么加入 nice 值后,將會使得 PRI 變為: PRI(new)=PRI(old)+nice ,
到目前為止,更需要強調一點的是,行程的 nice 值不是行程的優先級,他們不是一個概念,但是行程 nice 值會影響到行程的優先級變化,
通過調整 nice 值,更改行程優先級, nice 調整范圍是 -20~19 ,
行程優先級與變動影響因素與原理
調度策略: RR 調度和 FIFO 調度的行程屬于實時行程,以分時調度( OTHER )的行程是非實時行程,
FIFO (先進先出)和 RR (時間片輪轉)用于實時行程, OTHER (分時調度)用于非實時行程;實時行程會搶占普通行程; FIFO 會導致同優先級實時行程始終占用 CPU , RR 會保證同優先級實時行程按時間片輪流執行,
參考:SCHED_OTHER,SCHED_FIFO,SCHED_RR
實時行程優先級高于普通行程,實時行程使用靜態優先級調度、非實時行程使用動態優先級調度,非實時行程動態優先級通過 nice 調整、可能受 bonus 影響,
Linux行程有兩種優先級:普通行程優先級(使用 SCHED_NORMAL 調度策略),以及實時行程優先級(使用 SCHED_FIFO 或 SCHED_RR 調度策略)
不同調度策略的實時行程只有在相同優先級時才有可比性,任何時候,實時行程的優先級都高于普通行程
Linux對實時行程使用靜態優先級調度,對普通的行程(非實時行程),根據動態優先級進行調度,
實時行程,只有靜態優先級(在 0~MAX_RT_PRIO-1 間,默認 MAX_RT_PRIO 為 100 ), 內核不會再根據休眠等因素對其靜態優先級做調整;
實時行程 0-99 號優先級每一個優先級對應一個優先級佇列(鏈表),先執行數值高的對應的鏈表(0號最低),可由后面所述的 chrt 以及 相應函式修改該優先級;
非實時行程靜態優先級可通過 nice 值( -20~19 )調整: static_prio=MAX_RT_PRIO + nice + 20 ,
nice 只影響非實時行程(靜態優先級在 100~139 之間), nice 越大靜態優先級值越大,優先級越低,
非實時行程動態優先級根據靜態優先級和 bonus 計算: dynamic_prio = max (100, min (static_prio - bonus + 5, 139))
bonus 反映行程平均睡眠時間(范圍 0~10 ),睡眠時間越多越可能是互動行程,每次輪到它運行時它就越可能不會使用完時間片再釋放 cpu ,
查看與設定優先級與行程執行緒資訊等的方法
通過 ps 查看行程資訊
ps -el 可查看行程優先級和nice值,命令執行結果:NI列顯示的每個行程的nice值(主要針對非實時行程),PRI是行程的優先級(如果是實時行程就是靜態優先級,如果是非實時行程,就是動態優先級),
通過 top 查看行程資訊
其中的優先級和ps的pri不一樣,ps中一般為0的行程,在top中為20,這個優先級應該對應于前面所說的實時行程優先級,實時行程只使用1-99號優先級佇列,序號越大優先級越高,0號留給普通行程使用,
chrt -p 查看行程屬性
通過 chrt 查看和修改行程調度和優先級屬性,它一般也是呼叫后面的 sched_setscheduler() 實作的,
注意: char -o pri command 設定為SCHED_OTHER調度方式優先級別值只能是0表示比任何實時優先級都低,非實時行程不使用該值決定調度行為,普通行程使用自己的調度策略,
參考: man chrt
通過 sched_setscheduler() 設定行程調度和優先級屬性
效果類似 chrt,
關于priority的注意:這里引數中的pri不是ps的nice也不是priority,而是代碼中的sched_priority,用于表示一系列可執行行程串列,實時行程中該值范圍為1-99越大表示優先級越高, 非實時只能是0表示始終比實時行程低,并且非實時行程的優先級不由此值確定而是由其內部動態優先級確定,chrt中的pri應該也類似含義,例如: chrt -f -p 10 pid 則ps中pri為-11, chrt -f -p 1 pid 則ps中pri為-2)為0,行程命令為command,其它可以根據選項引數設定,
關于prioriti的注意:一般子行程會繼承父行程的調度策略,在Linux 2.6.32之后,可以使用 SCHED_RESET_ON_FORK 按位與引數的方式呼叫 sched_setscheduler(), 使用之后效果是:如果呼叫行程使用 SCHED_FIFO 或 SCHED_RR 調度策略,使用 SCHED_RESET_ON_FORK 后fork創建的子行程創建時將會自動重置為 SCHED_OTHER 調度策略;如果呼叫行程使用負值nice,那么使用 SCHED_RESET_ON_FORK 后fork創建的子行程創建時將會自動將其nice重置為0, 這個標記激活時只有當行程具有 CAP_SYS_NICE 標記時才能被重置,而這個 CAP_SYS_NICE 標記在使用fork()創建子行程后,在子行程中被禁止,
參考: man sched_setscheduler
通過 pthread_attr_setschedpolicy() 設定執行緒調度和優先級屬性
效果類似 sched_setscheduler(), 但是用于執行緒而非行程,
參考: man pthread_attr_setschedpolicy
關注公眾號,分享更多你感興趣的互聯網技術內容!

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/240149.html
標籤:其他
上一篇:互聯網面試六大常見問題及應對技巧,2021不再入坑!
下一篇:ssm搭建拍賣系統
