註:preempty 是一種插隊的行為,像救護車,可翻作...。
由於 thread 是 preemptive 的,同一 process 內不同 thread 共用的資料,可能修改到一半有其它 thread 存取而造成錯誤 (修改被覆蓋、資料結構破壞等),所以需要 mutex 保護。函式可能重複呼叫,要看是否可以 reentry。
每個 thread 有各自的 policy 及 priority 來決定排程,都會 preemptive 執行 priority 值最大的,相同 priority 的再由 policy 安排如何執行。thread 建立時會繼承 policy 及 priority。
| 等級 | policy | priority | 說明 |
|---|---|---|---|
| 一般 | SCHED_OTHER (預設) | 0 | 參考 nice 值動態調整 CPU 時間的使用比例,讓每個 thread 輪流、不用等候太久都能分配到 CPU 時間,滿足互動式多工系統。 |
| SCHED_BATCH | 2.6.16+。類似 SCHED_OTHER,但排程會減少喚醒次數來減少 thread 切換,一般用在非互動式的程式。 | ||
| SCHED_IDLE | 2.6.23+。以最低優先權執行。 | ||
| (soft) real time | SCHED_FIFO | 1~99 | 一開始先插隊執行,之後次序照先後排隊。每次執行直到等待 IO 或讓出。 |
| SCHED_RR | 同 SCHED_FIFO,但每次執行有 time slice 時間限制。 | ||
| SCHED_DEADLINE | Linux 3.14+ |
nice 值 (在 POSIX 是 process 層級的屬性,但目前 Linux/NPTL 實作是 thread 層級的屬性。)
- 範圍 -20 ~ 19,預設 0,值越大越「好心」,排程分配的份量越少。對應到 kernel 內部表示的範圍是 40 ~ 1,相當於 20 - nice 值。不同 kernel 版本排程演算法有所不同。
- 可以提高自己的 nice 值,只有 privileged thread 才能降低或設為負值 (chap35.3.2)。自從 Linux 2.6.12,process 有適當的 RLIMIT_NICE 軟性限制 (見 getrlimit()) 可以降低 nice 值。
- round-robin timing-sharing 的 CPU 時間分配,滿足互動式多工系統需要的 Fairness (公平) 和 Responsive (不用等太久),按順序都會分配到 (不會餓死) time slice 或 quantum 的時間,除非自願放棄 (休息或等候) 才會縮短。
- 會繼承
- Linux 2.6.38 新增 "autogroup" 功能代表 nice 值在許多 circumstances 不再有其傳統效果。
- getpriority(which, who):取得 which 中 who 裡 nice 值最小的。
- which 可以是 PRIO_PROCESS (指 thread)、PRIO_PGRP、或 PRIO_USER,決定 who 是 process ID、process group ID、或 user ID。who 為 0 表示本身所屬 process、process group、或 user。
- 由於 -1 可能是有效的值或錯誤,需先設 errno 為 0,如果回傳值是 -1 時,需檢查 errno 判別。
- setpriority(which, who, value):
- 有 CAP_SYS_NICE 權限可設其它 thread nice 值
- 沒權限只能增加符合 real 或 effective user ID 的 thread。Kernel v2.6.12+ 的 RLIMI_NICE 限定可設定的範圍。
- nice(incr)
- 指令 nice
- 指令 renice
CPU affinity mask => 在多處理器系統決定可使用哪些處理器。
註:sched_get_priority_min(policy) 及 sched_get_priority_max(policy) 取得特定 policy 的 priority 範圍。
註:sched_setscheduler() 設定 pid 或自己的 policy 及 priority,而sched_setparam() 只設定 priority。sched_getscheduler()、sched_getparam() 分別取得 policy 和 prioity。在 2.6.12 以前, CAP_SYS_NICE 的 process 才能設定 policy 和 priority。另外,SCHED_OTHER process 的 real/effective user ID 和我的effective user ID 相同的,也可以設定。2.6.12 之後新增 RLIMIT_RTPRIO...。
s
避免 realtime process locking up 整個系統
- 用 setrlimit() 設定適合的 low soft CPU time resource limit (RLIMIT_CPU, described in Section 36.3),如果 consumes too much CPU time 會送 SIGXCPU signal,預設 kill the process。
- 用 alarm() 設定 alarm timer,如果執行超過時間會 killed by a SIGALRM signal。
- 建立 watchdog process 執行在較高 realtime priority,無限迴圈 sleep 一段時間檢查其它 process 狀態,可順便量測 CPU time (Section 23.5.3 的 clock_getcpuclockid()) 和檢查 policy 和 priority,可降低 priority 或送 signal 停止會結束它。
- 2.6.25 開始提供 RLIMIT_RTTIME 限制一次持續 CPU time 用量,送 signal SIGXCPU。細節見 Documentation/ scheduler/sched-rt-group.txt。
sched_yield()
註:sched_rr_get_interval() 取得 SCHED_RR 每次執行時間。
註:2.6.25+ /proc/sys/kernel/sched_rt_period_us/proc/sys/kernel/sched_rt_runtime_u
參考來源:
20200713 最後更新
沒有留言:
張貼留言