1. 程式人生 > 其它 >從上帝視角看OS程序排程

從上帝視角看OS程序排程

下面所屬以Linux 1.1.0原始碼為例(Linux初期版本,原始碼1w多行,推薦閱讀原始碼,或看相關書籍 Linux核心(v1.2.0)註釋

相關部件:

Linux OS

CPU:有自己的頻率,通常很高(如筆者當前機器的CPU頻率為1.3GHZ,即其暫存器的操作延遲為0.8ns左右),因此可以在1秒內做非常多的事。

可程式設計定時器/計數器Timer:有自己的頻率,Linux原始碼中定為100,即 10ms 觸發一次。OS內的很多時間計數以此為單位,如OS滴答數的單位、程序排程的時間片的單位都是Timer的週期。

背景:

程序是OS資源分配的基本單位、執行緒是CPU排程的基本單位。但在Linux核心中實際上沒有執行緒概念,我們所說的執行緒在Linux核心中是輕量級程序LWP,其資料就結構表示與程序一樣,從這角度看,核心中就是程序(或稱任務)排程。

OS程序排程就是OS選擇一個程序讓它獲得CPU執行權的過程。程序獲得CPU執行權後就可以執行其程式碼了,但不是無限執行——會由OS設定一個可執行時長(稱為時間片或時間計數器),通常是Timer週期的倍數。

CPU收到中斷請求時會從固定的地址去查詢中斷向量表,並根據中斷請求號從表中取得對應的中斷處理函式執行。

對於不同的OS,中斷向量表內容、同一個中斷號對應的中斷處理函式都可能不同,這些是在由OS在初始化時設定的。如(sched.c):set_intr_gate(0x20, &timer_interrupt);

程序排程的原理概要:

Timer 每次觸發時向CPU發出時間中斷請求:10ms一次,中斷號為20。

CPU響應時間中斷請求:找到該中斷號對應的中斷處理函式timer_interrupt並執行。

該函式邏輯:若當前在執行的程序的時間片未用完則程序繼續執行且時間片減1,否則呼叫函式sched.c進行程序排程。

後者的邏輯:從所有RUNNABLE狀態的程序中選擇時間片counter最大者(若值都為0則包括非RUNNABLE的所有程序的counter重新賦值 counter = counter/2 + priority,然後重新選程序),切換(類似於函式呼叫,從CPU暫存器獲取當前程序上下文資訊並儲存到記憶體棧,新程序上下文資訊設定到CPU暫存器即可)到該程序執。

可見,程序排程的始驅動力就是Timer,OS巧妙地利用了Timer、CPU、時間中斷來定期地進行程序排程,這個“定期”就是Timer的週期長。

上述過程是在v1.1.0原始碼中的原理,如今版本可能已經差別較大,但原理相通。萬變不離其宗。

詳情推薦參閱:上帝視角看程序排程—公眾號地併發程式設計Linux核心(v1.2.0)註釋