詳細剖析Linux程序排程時機

2021-07-04 09:41:47 字數 2377 閱讀 5680

linux在眾多程序中是怎麼進行排程的,這個牽涉到linux程序排程時機的概念,由linux核心中schedule()的函式來決定是否要進行程序的切換,如果要切換的話,切換到哪個程序等等。

linux程序排程時機主要有

1、程序狀態轉換的時刻:程序終止、程序睡眠;

2、當前程序的時間片用完時(current->counter=0);

3、裝置驅動程式

4、程序從中斷、異常及系統呼叫返回到使用者態時;

時機1,程序要呼叫sleep()或exit()等函式進行狀態轉換,這些函式會主動呼叫排程程式進行程序排程;

時機2,由於程序的時間片是由時鐘中斷來更新的,因此,這種情況和時機4是一樣的。

時機3,當裝置驅動程式首席執行官而重複的任務時,直接呼叫排程程式。在每次反覆迴圈中,驅動程式都檢查need_resched的值,如果必要,則呼叫排程程式schedule()主動放棄cpu。

時機4,如前所述,不管是從中斷、異常還是系統呼叫返回,最終都呼叫ret_from_sys_call(),由這個函式進行排程標誌的檢測,如果必要,則呼叫呼叫排程程式。那麼,為什麼從系統呼叫返回時要呼叫排程程式呢?這當然是從效率考慮。從系統呼叫返回意味著要離開核心態而返回到使用者態,而狀態的轉換要花費一定的時間,因此,在返回到使用者態前,系統把在核心態該處理的事全部做完。

對於直接執行排程程式的時機,我們不討論,因為後面我們將會描述排程程式的工作過程。前面我們討論了時鐘中斷,知道了時鐘中斷的重要作用,下面我們就簡單看一下每個時鐘中斷發生時核心要做的工作,首先對這個最頻繁的排程時機有乙個大體了解,然後再詳細討論排程程式的具體工作過程。

每個時鐘中斷(timer interrupt)發生時,由三個函式協同工作,共同完成程序的選擇和切換,它們是:schedule()、do_timer()及ret_form_sys_call()。我們先來解釋一下這三個函式:

schedule():程序排程函式,由它來完成程序的選擇(排程);

do_timer():暫且稱之為時鐘函式,該函式在時鐘中斷服務程式中被呼叫,是時鐘中斷服務程式的主要組成部分,該函式被呼叫的頻率就是時鐘中斷的頻率即每秒鐘100次(簡稱100赫茲或100hz);

ret_from_sys_call():系統呼叫返回函式。當乙個系統呼叫或中斷完成時,該函式被呼叫,用於處理一些收尾工作,例如訊號處理、核心任務等等。

這三個函式是如何協調工作的呢?

前面我們看到,時鐘中斷是乙個中斷服務程式,它的主要組成部分就是時鐘函式do_timer(),由這個函式完成系統時間的更新、程序時間片的更新等工作,更新後的程序時間片counter作為排程的主要依據。

在時鐘中斷返回時,要呼叫函式ret_from_sys_call(),前面我們已經討論過這個函式,在這個函式中有如下幾行:

cmpl $0, _need_resched

jne reschedule

restore_all:

restore_all

reschedule:

call symbol_name(schedule)

jmp ret_from_sys_call

這幾行的意思很明顯:檢測 need_resched 標誌,如果此標誌為非0,那麼就轉到reschedule處呼叫排程程式schedule()進行程序的選擇。排程程式schedule()會根據具體的標準在執行佇列中選擇下乙個應該執行的程序。當從排程程式返回時,如果發現又有排程標誌被設定,則又呼叫排程程式,直到排程標誌為0,這時,從排程程式返回時由restore_all恢復被選定程序的環境,返回到被選定程序的使用者空間,使之得到執行。

以上就是時鐘中斷這個最頻繁的排程時機。討論這個的主要目的使讀者對時機4有個大致的了解。

最後要說明的是,系統呼叫返回函式ret_from_sys_call()是從系統呼叫、異常及中斷返回函式通常要呼叫的函式,但並不是非得呼叫,對於那些要經常被響應的和要被盡快處理的中斷請求訊號,為了減少系統開銷,處理完成後並不呼叫 ret_from_sys_call()(因為很顯然的,從這些中斷處理程式返回到的使用者空間肯定是那個被中斷的程序,無需重新選擇),並且,它們作的工作要盡可能少,因為響應的頻率太高了。

linux程序排程和其他的unix程序排程不同,尤其是在「nice level」優先順序的處理上,與優先權排程(priority高的程序最先執行)不同,linux用的是時間片輪轉排程(round robing),但同時又保證了高優先順序的程序執行的既快、時間又長(both sooner and longer)。而標準的unix排程程式都用到了多級程序佇列。大多數的實現都用到了二級優先佇列:乙個標準佇列和乙個實時(「real time」)佇列。一般情況下,如果實時佇列中的程序未被阻塞,它們都要在標準佇列中的程序之前被執行,並且,每個佇列中,「nice level」高的程序先被執行。

總體上,linux 排程序程在互動性方面表現很出色,當然了,這是以犧牲一部分「吞吐量」為代價的。

程序排程時機跟蹤分析程序排程與程序切換的過程

張磊 程序的排程時機與程序的切換 作業系統原理中介紹了大量程序排程演算法,這些演算法從實現的角度看僅僅是從執行佇列中選擇乙個新程序,選擇的過程中運用了不同的策略而已。對於理解作業系統的工作機制,反而是程序的排程時機與程序的切換機制更為關鍵。程序排程的時機 下面是整個實驗過程 網易實驗樓環境 程序切換...

程序詳細剖析(二)

摘自 c 多核高階程式設計 5.6.3 程序狀態 在程序執行期間,它的狀態會發生改變。程序的狀態時指程序的當前狀況。在posix相容的環境中,程序可以處於以下狀態 1 執行 running 2 就緒 runnable,ready 3 僵死 zombied 4 等待 waiting,blocked 5...

程序排程詳細總結

無論是在批處理系統 還是分時系統 中,使用者程序數一般都多於 處理機數 這將導致它們互相爭奪處理機。另外,系統程序也同樣需要使用處理機。這就要求程序排程程式按一定的策略,動態地把處理機分配給處於就緒佇列中的某乙個程序,以使之執行。1.多型性 從誕生 執行,直至消滅。2.多個不同的程序可以包括相同的程...