「作業系統的排程器(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