Linux 進程調度管理
進程調度器
現代計算機系統中既包含只有單個CPU且任何時候都只能處理單個指令的低端系統到具有幾百個cpu、每個cpu有多個核心的高性能超級計算機,可以并行執行幾百個指令。所有這些系統都有一個共同點:系統進程線程數量超出了CPU數量。
Linux系統看起來可以同時執行多個進程,多個進程輪流使用CPU。內核使用進程調度器決定如何分配CPU時間。為了更好地運行,進程調度器必須平衡不同的條件,快速決定下個執行的進程,確保進程獲得公平的CPU時間:
- 按時間片輪轉(10-20ms為1個時間片 )
- 按優先級調度,允許高優先級進程獲取更多的共享CPU時間,低優先級進程獲取更少的共享CPU時間。
實時調度器
實時調度器支持的調度策略:
- SCHED_RR,roundrobin 輪訓調度策略。相同優先級的進程輪流獲取相同的CPU時間。
- SCHED_FIFO,先入先出調度策略。被分配到的CPU時間的進程會一直運行,直到被IO阻塞(也稱為sched_yield),會被高優先級進程搶占。
實時調度器管理的進程運行優先級范圍如下:
即使系統運行實時調度程序,也要保持可響應狀態,至少ssh可用。
管理員可以使用以下兩個sysctl參數,阻止實時調度策略下運行的程序占用所有CPU時間:
-
kernel.sched_rt_runtime_us,在kernel.sched_rt_period_us內實時態進程可使用的共享CPU時間,默認值950000,也就是0.95秒。設置為0,實時調度進程將無法獲取CPU時間。
-
kernel.sched_rt_period_us,CPU分配的周期時間,單位us,默認值1000000,也就是1秒。
從kernel.sched_rt_period_us 中減去 kernel.sched_rt_runtime_us 后的剩余時間交給非實時調度器SCHED_NORMAL調度。
-
kernel.sched_rr_timeslice_ms,在SCHED_RR調度下的進程每次輪詢獲取的CPU時間,單位ms,默認值100,也就是0.1秒,有效范圍1-100。
非實時調度器
非實時調度器支持的調度策略:
- SCHED_NORMAL,標準的輪詢方式時間共享調度,也稱為SCHED_OTHER。
- SCHED_BATCH,針對批量方式執行的進程策略。不像 SCHED_NORMAL 頻繁競爭,任務可以長時間運行。
- SCHED_IDLE,用于執行非常低的優先級應用。使用 SCHED_IDLE 調度策略運行的進程比nice 19運行的進程優先級還低。
管理進程優先級-非實時調度策略
nice 值
常規系統上運行的大多數進程都使用 SCHED_OTHER 調度策略。由于并非所有進程都同等重要,因此可以為使用SCHED_OTHER調度策略運行的程序指定相對優先級,稱為nice值。
有40種不同級別的nice值,范圍 -20(最高優先級)到 19(最低優先級):
- nice 值越高,代表優先級越低,獲取CPU能力越弱。
- nice 值越低,代表優先級越高,獲取CPU能力越強。
注意: 當不存在CPU資源競爭時,即使nice值高的進程也可以獲得足夠CPU資源。
nice 值查看
top 命令
ps命令
[li@server ~ 19:10:58]$ ps -o nice,cmd $(pgrep systemd)NI CMD0 /usr/lib/systemd/systemd --switched-root --system --deserialize 220 /usr/lib/systemd/systemd-journald0 /usr/lib/systemd/systemd-udevd0 /usr/lib/systemd/systemd-logind
默認情況下,子進程將繼承父進程的nice值,通常為0。
[li@server ~ 19:23:39]$ md5sum /dev/zero &
[1] 68517
[li@server ~ 19:24:18]$ ps -o pid,nice,command $$ 68517PID NI COMMAND60940 0 -bash68517 0 md5sum /dev/zero# $$ 代表當前終端中運行的 shell 程序 PID
實時調度器進程優先級和非實時調度器進程優先級對比如下:
結論: 優先級最低的實時調度器進程的優先級高于優先級最高的非實時調度器進程的優先級。
nice 命令
[li@server ~ 19:24:34]$ nice --help
用法:nice [選項] [命令 [參數]...]
Run COMMAND with an adjusted niceness, which affects process scheduling.
With no COMMAND, print the current niceness. Niceness values range from
-20 (most favorable to the process) to 19 (least favorable to the process).Mandatory arguments to long options are mandatory for short options too.-n, --adjustment=N add integer N to the niceness (default 10)--help 顯示此幫助信息并退出--version 顯示版本信息并退出
示例:
# nice值默認是10
[li@server ~ 19:25:59]$ nice md5sum /dev/zero &
[2] 68730[li@server ~ 19:27:59]$ ps -o pid,nice,commandPID NI COMMAND60940 0 -bash68517 0 md5sum /dev/zero68730 10 md5sum /dev/zero68736 0 ps -o pid,nice,command
普通用戶僅允許使用正數的nice值運行程序。
# 設置一個負數優先級
[li@server ~ 19:28:05]$ nice -n -2 md5sum /dev/zero &
[3] 68797
[li@server ~ 19:29:09]$ nice: 無法設置優先級: 權限不夠
^C
[li@server ~ 19:29:25]$ ps -o pid,nice,command 68797PID NI COMMAND68797 0 md5sum /dev/zero# 設置一個正數優先級
[li@server ~ 19:29:35]$ nice -n 2 md5sum /dev/zero &
[4] 68869
[li@server ~ 19:30:02]$ ps -o pid,nice,command 68869PID NI COMMAND68869 2 md5sum /dev/zero
renice 命令
[li@server ~ 19:30:19]$ renice --help用法:renice [-n] <優先級> [-p|--pid] <pid>...renice [-n] <優先級> -g|--pgrp <pgid>...renice [-n] <優先級> -u|--user <用戶>...選項:-g, --pgrp <id> 將參數解釋為進程組 ID-n, --priority <數字> 指定 nice 增加值-p, --pid <id> 將參數解釋為進程 ID (默認)-u, --user <name|id> 將參數解釋為用戶名或用戶 ID-h, --help 顯示幫助文本并退出-V, --version 顯示版本信息并退出
修改上面示例中產生的進程的優先級。
[li@server ~ 19:30:53]$ renice -n 2 68797
68797 (進程 ID) 舊優先級為 0,新優先級為 2
[li@server ~ 19:31:55]$ ps -o pid,nice,command 68797PID NI COMMAND68797 2 md5sum /dev/zero# 使用root用戶調整
[root@server ~ 19:12:42]# renice -n -2 68797
68797 (進程 ID) 舊優先級為 2,新優先級為 -2
[root@server ~ 19:32:57]# renice -n -2 68869
68869 (進程 ID) 舊優先級為 2,新優先級為 -2
[root@server ~ 19:33:30]# ps -o pid,nice,command 68797 68869PID NI COMMAND68797 -2 md5sum /dev/zero68869 -2 md5sum /dev/zero
top 命令
top 界面查看進程CPU使用率:68797和68869,CPU使用率非常接近,因為優先級一致。
在該界面中使用 r 指令設置進程nice值。
終止之前創建的4個md5sum進程。
[li@server ~ 19:32:25]$ pkill md5sum
[1] 已終止 md5sum /dev/zero
[2] 已終止 nice md5sum /dev/zero
[4]+ 已終止 nice -n 2 md5sum /dev/zero
[3]+ 已終止 nice -n -2 md5sum /dev/zero
管理進程優先級-實時調度策略
chrt 命令用于獲取和設置實時調度器進程優先級,以及更改進程調度器。
[root@server ~ 19:35:46]# chrt --help
Show or change the real-time scheduling attributes of a process.Set policy:chrt [options] <priority> <command> [<arg>...]chrt [options] --pid <priority> <pid>Get policy:chrt [options] -p <pid>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 <ns> runtime parameter for DEADLINE-P, --sched-period <ns> period parameter for DEADLINE-D, --sched-deadline <ns> deadline parameter for DEADLINEOther 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 顯示此幫助并退出-V, --version 輸出版本信息并退出更多信息請參閱 chrt(1)。
示例:
# 查看進程優先級范圍,chrt不能用于調整非實時進程nice值優先級。
[root@server ~ 19:37:16]# 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_RR調度器和優先級為5運行md5sum進程
[root@server ~ 19:38:40]# chrt -r 5 md5sum /dev/zero &
[2] 69391
[root@server ~ 19:39:03]# ps -o pid,cls,rtprio,command 69391PID CLS RTPRIO COMMAND69391 RR 5 md5sum /dev/zero# 修改進程調度器和優先級
[root@server ~ 19:39:17]# chrt -f --pid 10 69391
[root@server ~ 19:39:55]# ps -o pid,cls,rtprio,command 69391PID CLS RTPRIO COMMAND69391 FF 10 md5sum /dev/zero# 修改進程調度器為非實時
[root@server ~ 19:40:05]# chrt -o --pid 0 69391
[root@server ~ 19:40:33]# ps -o pid,cls,rtprio,command 69391PID CLS RTPRIO COMMAND69391 TS - md5sum /dev/zero