當Linux核心要尋找一個新的進程在CPU上運行時,必須只考慮處於可運行狀態的進程,(即在TASK_RUNNING狀態的進程),因為掃描整個進程鏈表是相當低效的,所以引入了可運行狀態進程的雙向迴圈鏈表,也叫運行隊列(runqueue)。
運行隊列容納了系統中所有可以啟動並執行進程,它是一個雙向迴圈隊列
該隊列通過task_struct結構中的兩個指標run_list鏈表來維持。隊列的標誌有兩個:一個是“空進程”idle_task、一個是隊列的長度。
有兩個特殊的進程永遠在運行隊列中待著:當前進程和空進程。前面我們討論過,當前進程就是由cureent指標所指向的進程,也就是當前運行著的進 程,但是請注意,current指標在調度過程中(發送器執行時)是沒有意義的,為什麼這麼說呢?調度前,當前進程正在運行,當出現某種調度時機引發了 進程調度,先前運行著的進程處於什麼狀態是不可知的,多數情況下處於等待狀態,所以這時候current是沒有意義的,http://Ubuntuone.cn/ 直到發送器選定某個進程投入運行後,current才真正指向了當前運行進程;空進程是個比較特殊的進程,只有系統中沒有進程可運行時它才會被執 行,Linux將它看作運行隊列的頭,當發送器遍曆運行隊列,是從idle_task開始、至idle_task結束的,在發送器運行過程中,允許隊 列中加入新出現的可運行進程,新出現的可運行進程插入到隊尾,這樣的好處是不會影響到發送器所要遍曆的隊列成員,可見,idle_task是運行隊列很 重要的標誌。
另一個重要標誌是隊列長度,也就是系統中處於可運行狀態(TASK_RUNNING)的進程數目,用全域整型變數nr_running表示,在/kernel/fork.c中定義如下:
int nr_running=1;
若 nr_running為0,就表示隊列中只有空進程。在這裡要說明一下:若nr_running為0,則系統中的當前進程和空進程就是同一個進程。但是Linux會充分利用CPU而盡量避免出現這種情況。