1. 資料結構:
- 優先級隊列
struct prio_array {
unsigned int nr_active; 表示等待執行的程序總數
unsigned long bitmap[BITMAP_SIZE]; 一個unsigned long在核心中隻有32位哈,大家要跟64位OS上的C程式中的long區分開,那個是64位的。那麼這個bitmap是幹什麼的呢?它是用位的方式,表示某個優先級上有沒有待處理的隊列,是實作快速找到最高待處理優先程序的關鍵。如果我定義了四種優先級,我隻需要四位就能表示某個優先級上有沒有程序要運作,例如優先級是2和3上有程序,那麼就應該是0110.......非常省空間,效率也快,不是嗎?
struct list_head queue[MAX_PRIO]; 與上面的bitmap是對應的,它存儲所有等待運作的程序。
};
- 運作隊列
struct runqueue {
spinlock_t lock; 這是個自旋鎖,nginx裡解決驚群現象時也是用這個。與普通鎖的差別就是,使用普通鎖時,你去試圖拿一把鎖,結果發現已經被别人拿走了,你就在那睡覺,等别人鎖用完了叫你起來。是以如果有一個人拿住鎖了,一百個人都在門前睡覺等。當之前的人用完鎖回來後,會叫醒所有100個等鎖的人,然後這些人開始互相搶,搶到的人拿鎖進去,其他的人繼續等。自旋鎖不同,當他去拿鎖發現鎖被别人拿走了,他在那不睡覺的等,稍打個盹就看看自己主動看看鎖有沒有還回來。大家比較出優劣了嗎?
unsigned long nr_running;
#ifdef CONFIG_SMP
unsigned long cpu_load;
#endif
unsigned long long nr_switches;
unsigned long nr_uninterruptible;
unsigned long expired_timestamp;
unsigned long long timestamp_last_tick;
task_t *curr, *idle;
struct mm_struct *prev_mm;
prio_array_t *active, *expired, arrays[2];上面說了半天的優先級隊列在這裡,但是在runqueue裡,為什麼不隻一個呢?這個在下面講。
int best_expired_prio;
atomic_t nr_iowait;
... ...
};
Reference:
- linux核心排程算法(1)--快速找到最高優先級程序
- Linux 2.6 排程系統分析
- https://elixir.bootlin.com/linux/v2.6.11/source/include/linux/sched.h
- https://elixir.bootlin.com/linux/v2.6.11/source/kernel/sched.c