「作業系統的排程器(scheduler)提供好幾種排程演算法,並在不同的應用場合,或是不同的 process 採取適合的排程策略(policy)。」
Linux 的 process descriptor 資料結構為 struct task_struct,我們最早開始談論與 process 有關的 system call 時,就看過這個用來描述 process 的資料結構。struct task_struct 裡頭的 policy 欄位便是用來描述該 process 的排程策略。
與排程有關的系統呼叫
整理與 scheduling 有關的幾個 system call 如下(可參考「Linux 2.6 的 System Call:12 大類」),另外 Jollen 也把到目前為止已介紹過的 system call 加上紅色註記。
號碼 | System Call 名稱 | Manipulation |
34 |
sys_nice | 關於 struct task_struct->nice 欄位。 |
154 |
sys_sched_setparam | 關於 struct task_struct->rt_priority 欄位。 |
155 |
sys_sched_getparam | 關於 struct task_struct->rt_priority 欄位。 |
156 |
sys_sched_setscheduler | 關於 struct task_struct->policy 欄位。(這是下一個要讀的) |
157 |
sys_sched_getscheduler | 關於 struct task_struct->policy 欄位。 |
158 |
sys_sched_yield | 暫不討論。 |
159 |
sys_sched_get_priority_max | 根據 'policy' 傳回 'rt_priority' 所允許的最大 priority 值。 |
160 |
sys_sched_get_priority_min | 根據 'policy' 傳回 'rt_priority' 所允許的最小 priority 值。 |
161 |
sys_sched_rr_get_interval | 若 policy 為 SCHED_RR(Round Robin policy),則傳回 time quantum(time slice)值。 |
241 |
sys_sched_setaffinity | 這是 Linux 2.6 新增加的 system call。 |
242 |
sys_sched_getaffinity | 這是 Linux 2.6 新增加的 system call。 |
「'sys_sched_getscheduler' 便是用來取得 process 排程策略(policy)的 system call。」
「'struct task_struct->policy' 是今天要了解的主題。」
我們想要思考一個問題「作業系統的教科書提到的排程演算法中,Round Robin 是我們知道現在的分時作業系統(eg. Linux)所採用的策略,所以我想了解 Linux 的 process descriptor 裡,是哪一個 field 在紀錄這件事情。」
struct task_struct 的 policy 欄位
這個問題還挺簡單的,因為直接看 struct task_struct 幾乎就能猜到是哪一個 field,再用谷歌找資料來印證我們的設假;另外,看「Understanding the Linux Kernel」也寫的很清楚。
struct task_struct { ... unsigned long policy; ... };
接著再回頭來看今天的主題,sys_sched_getscheduler 的實作(Linux 2.6.11+):
/** * sys_sched_getscheduler - get the policy (scheduling class) of a thread * @pid: the pid in question. */ asmlinkage long sys_sched_getscheduler(pid_t pid) { int retval = -EINVAL; task_t *p; // jollen: 'typedef struct task_struct task_t;' if (pid < 0) goto out_nounlock; retval = -ESRCH; read_lock(&tasklist_lock); p = find_process_by_pid(pid); // 參照說明 1. if (p) { retval = security_task_getscheduler(p); if (!retval) retval = p->policy; // 參照說明 2. } read_unlock(&tasklist_lock); out_nounlock: return retval; }
取出重點部位來看:
很簡單的將 sys_sched_getscheduler 看了一下,並且了解到 policy 欄位的用途。
find_process_by_pid
把 find_process_by_pid() 的實作拿出來看:
/** * find_process_by_pid - find a process with a matching PID value. * @pid: the pid in question. */ static inline task_t *find_process_by_pid(pid_t pid) { return pid ? find_task_by_pid(pid) : current; }
發現一件很重要的是,也是之前都沒提過的。
「若 PID 為 0,則傳回 current,否則傳回 PID 為 pid 的 process 之 process descriptor。」
別忘了,current 的 data type 也是 'struct task_struct'。
Linux 排程策略:policy 欄位的值
Linux 2.6 提供的排程策略如下:
/* * Scheduling policies */ #define SCHED_NORMAL 0 #define SCHED_FIFO 1 #define SCHED_RR 2 #define SCHED_BATCH 3
定義在 include/linux/sched.h。順帶把 Linux 2.4 提供的排程策略也節錄一下:
/* * Scheduling policies */ #define SCHED_OTHER 0 #define SCHED_FIFO 1 #define SCHED_RR 2
Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue
您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw