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

2021-07-02 01:46:13 字數 3812 閱讀 7350

張磊+ 

程序的排程時機與程序的切換

作業系統原理中介紹了大量程序排程演算法,這些演算法從實現的角度看僅僅是從執行佇列中選擇乙個新程序,選擇的過程中運用了不同的策略而已。

對於理解作業系統的工作機制,反而是程序的排程時機與程序的切換機制更為關鍵。

程序排程的時機

下面是整個實驗過程:(網易實驗樓環境)

程序切換的第二節由

switch_to

巨集執行。它是核心中與硬體關係最密切的例程之一,要理解它到低做了些什麼我們必須下些功夫。

首先,該巨集有三個引數,它們是

prev,next

和last

。你可能很容易猜到

prev

和next

的作用:它們僅是區域性變數

prev

和next

的佔位符,即它們是輸入引數,分別表示被替換程序和新程序描述符的位址在記憶體中的位置。

那第三個引數

last

呢?在任何程序切換中,涉及到三個程序而不是兩個。假設核心決定暫停程序

a而啟用里程b。在

schedule()

函式中,

prev指向a

的描述符而

next指向b

的描述符。

switch_to

巨集一但使

a暫停,

a的執行流就凍結。

隨後,當核心想再次此啟用

a,就必須暫停另乙個程序

c,於是就要用

prev指向c

而next指向a

來執行另乙個

swithch_to

巨集。當a

恢復它的執行流時,就會找到它原來的核心棧,於是

prev

區域性變數還是指向

a的描述符而

next指向b

的描述符。此時,代表程序

a執行的核心就失去了對

c的任何引用。但是,事實表明這個引用對於完成程序切換是很有用的。

switch_to

巨集的最後乙個引數是輸出引數,它表示巨集把程序

c的描述符位址寫在記憶體的什麼位置了。在程序切換之前,巨集把第乙個輸入引數

prev

表示的變數的內容存入

cpu的

eax暫存器。在完成程序切換,

a已經恢復執行時,巨集把

cpu的

eax暫存器的內容寫入由第三個輸出引數

-------last

所指示的

a在記憶體中的位置。因為

cpu暫存器不會在切換點發生變化,所以

c的描述符位址也存在記憶體的這個位置。在

schedule()

執行過程中,引數

last指向a

的區域性變數

prev

,所以prev被c

的位址覆蓋。 在

eax和

edx暫存器中分別儲存

prev

和next

的值。

movlprev ,%eax

movlnext ,%edx

把eflags

和ebp

暫存器的內容儲存在

prev

核心棧中。必須儲存它們的原因是編譯器認為在

switch_to

結束之前它們的值應當保持不變。

pushf1

push%ebp

把esp

的內容儲存到

prev->thread.esp

中以使該字段指向

prev

核心棧的棧頂:

movl%esp,484(%eax)

把next->thread.esp

裝入esp.

此時,核心開始在

next

的核心棧上操作,因此這條指令實際上完成了從

prev

到next

的切換。由於程序描述符的位址和核心棧的位址緊挨著,所以改變核心棧意味著改變程序。

movl484(5edx),%esp

把標記為

1的位址存入

prev->thread.eip

。當被替換的程序重新恢復執行時,程序執行被標記為

1的那條指令:

movl$lf,480(%eax)

巨集把next->thread.eip

的值壓入

next

的核心棧。

push1480(%edx)

跳到__switch_to()c函式

jmp__switch_to

這裡被程序

b替換的程序

a再次獲得

cpu;它執行一些儲存

eflags

和ebp

暫存器內容的指令,這兩條指令的第一條指令被標記為1。

拷貝eax暫存器的內容到

switch_to

巨集的第三個引數

lash

標識的記憶體區域中:

movl%eax,last

正如以前討論的,

eax暫存器指向剛被替換的程序描述符。

__switch_to()

函式執行大多數開始於

switch_to()

巨集的程序切換。這個函式作用於

prev_p

和next_p

引數,這兩個引數表示前乙個程序和新程序。這個函式的呼叫不同於一般函式的呼叫,因為

__switch_to()

從exa

和edx

取引數prev_p

和next_p

,而不像大多數函式一樣從棧中取引數。為了強迫函式從暫存器取它的引數,核心利用

__attribute__

和regparm

關鍵字,這兩個關鍵字是

c語言非標準的副檔名,由

gcc編譯程式實現。在

include/asm-i386/system.h

標頭檔案中,

__switch_to()

函式的宣告如下:

__switch_to(structtask_struct *prev_p,struct tast_struct *next_p)__attribute_(regparm(2));

小結:

程序的切換

schedule()函式選擇乙個新的程序來執行,並呼叫context_switch進行上下文的切換,這個巨集呼叫switch_to來進行關鍵上下文切換

程序排程的時機切換與過程排程方式

程序排程和切換程式是作業系統核心程式。請求排程的事件發生後,才可能執行程序排程程式,排程了新的就緒程序後,才會進行程序的切換。理論上這三件事情應該順序執行,但在實際設計中,作業系統核心程式執行時,若某時發生了程序排程的因素,則不一定能夠馬上進行排程與切換。不能進行程序的排程與切換的情況有以下情況 1...

八 程序排程的時機 切換與過程,排程方式

1.程序在作業系統核心程式臨界區不能進行排程與切換,但若說成程序處於臨界區時不能進行處理機排程是錯誤的。2.臨界資源 乙個時間段內只允許乙個程序使用的資源,各程序需要互斥的訪問臨界資源。臨界區 訪問臨界資源的那段 1.狹義的程序排程 與 程序切換 的區別 狹義的程序排程指的是從就緒佇列中選中乙個要執...

程序排程與作業排程

作業排程按一定的演算法從磁碟上的 輸入井 中選擇資源能得到滿足的作業裝入記憶體,使作業有機會去占用處理器執行。但是,乙個作業能否占用處理器,什麼時間能夠占用處理器,必須由程序排程來決定。所以,作業排程選中了乙個作業且把它裝入記憶體時,就應為該作業建立乙個程序,若有多個作業被裝入記憶體,則記憶體中同時...