進程

進程有時被稱爲任務,有時又被稱爲運行的程序。在這裏引用一段windows內核書籍抄過來的文字,這是迄今爲止最準確的定義:儘管表面上看起來程序和進程非常類似,但本質上它們卻是截然不同的。程序是指一個靜態的指令序列,而進程則是一個容器,其中包含了當執行一個程序的特定實例時所用到的各種資源。

進程就是各種資源的合集,通常一個進程包含下面幾種資源。

1、私有的線性地址空間:這是進程可以使用的線性地址的總和,其中內核部分可能和其他進程是共享的。

2、可執行的程序:也就是前面說的二進制序列,包含代碼和數據。

3、一些已經獲得的其他資源,如打開的文件管道等。

4、進程的權限:指進程的運行權限,在linux中有root和非root之分。

5、進程的描述符:有的操作系統又稱爲進程控制塊。包含操作該進程的一些必要信息。如進程ID號 。

進程是內核調度器調度的單元,進程的運行構成了操作系統工作的大部分內容,其機制較爲複雜。這裏只介紹和虛擬技術關係最爲緊密的概念---上下文。

上下文:

標題不是“進程的上下文”,是因爲還有一個“中斷的上下文”存在。上下文也是一個難以定義的概念,它實際上是從CPU的角度引出的。簡單的說,上下文就是程序運行時所需要的寄存器的最小集合。這些寄存器的後面可能代表着程序運行的一類資源,例如CR3寄存器就可以概括進程的私有線性地址空間。(分頁機制啓動時)

下面來看看x86架構上下文包含哪些寄存器。

1、通用寄存器組:即EAX、EBX、ECX、EDX、ESI、EDI這六個加上ESP(棧指針)、EBP(框架指針)。

2、段相關寄存器組:CS、DS、SS,如果程序是用來ES等額外的段寄存器也要包括進來。

3、標誌寄存器:主要是指EFLAGS寄存器。

4、程序指針寄存器:EIP。

5、GDT基地址:用於訪問GDT,GDTR中的內容。

6、LDT段選擇符:如果程序使用了私有的LDT,LDTR的內容。

7、IDT基地址:用於訪問IDT表,IDTR的內容。

8、控制寄存器組:CR系列,表示當前程序運行時的CPU控制狀態。

9、浮點相關寄存器組:用於浮點計算的一些寄存器組。

10、一些特殊用途的寄存器:例如x86架構的MSR。

一個程序的上下文可能是上面列出內容的一個子集(例如進程)也可能是全部(例如虛擬機)。從程序員的觀點來看,上下文的概念有些微改變,通常對於上下文切換時不需要改變的寄存器,也可以說它不是該程序的上下文。例如進程切換時,GDTR中的內容不需要改變,爲了方便,通常在一個講進程的上下文時不把GDTR算進去。在後面的內容中,包括虛擬機部分,提到上下文都是指在上下文切換時必須更改的寄存器的集合。

上下文切換

上下文切換是指程序從一種狀態切換到另一種狀態(例如用戶態切換到內核態)。或從一個程序切換到另一個程序(例如一個進程切換)時,導致上下文相關寄存器值的變化行爲。這種變化是指舊程序(切換前的程序)上下文相關的寄存器的值被保存到內存中,新程序(切換後的程序)上下文相關寄存器的值被加載到寄存器中。在操作系統中,通常只有三種情況會發生上下文切換。

1、用戶態到內核態的切換:此時的上下文切換是因爲進程的用戶態和內核態運行在不同的Ring級別,對資源的訪問權限不同,需要切換上下文。例如,從用戶態的棧切換到內核態的棧。

2、進程切換:由於一個CPU在同一時刻只能有一個進程運行,所以在新的進程運行前,需要把上下文相關寄存器的值換成新進程的相關值,例如把 CR3換成新進程頁目錄的地址,EIP指向新進程運行的第一條指令。這通常是上下文的切換。

3、到中斷上下文的切換:中斷的處理函數運行在特殊的上下文環境,稱爲中斷上下文。CPU處理一箇中斷時,不管當前CPU運行一個進程,還是本身就在一箇中斷上下文中,都要切換到新中斷的上下文。例如,更改棧指針、EIP變化等。這通常是部分上下文的切換,例如CR3寄存器的值就不需要更改。根據x86架構的特點,無論是linux的硬中斷機制還是window、solaris的中斷線程化機制,處理中斷必然經過一箇中斷上下文階段,可能的情況如下:

(1)進程上下文-》中斷上下文(處理中斷)-》進程上下文(中斷返回執行)

(2)進程上下文-》中斷上下文-》新進程上下文(處理中斷)-》進程上下文(最先被打斷進程的上下文)。

(3)中斷上下文-》新中斷上下文-》.......

x86只有一種機制,即任務門(Task Gate)可以使中斷的處理不經過中斷上下文而直接進入進程上下文,但幾乎沒有操作系統使用它,讀者可以忽略。

上下文的切換通常有兩個步驟。

1、保存舊上下文:將被切換出去的程序(如一個被新進程替代的舊進程)或將被切換出去的狀態(如程序的用戶態)的上下文相關寄存器的值保存在內存中。

2、加載新上下文:將要運行的程序(如新進程)或新狀態(如程序的內核態)運行需要的上下文相關寄存器的值從內存中讀入,加載入對應的寄存器中。

需要注意的是,保存舊的上下文動作在x86架構下有時會由CPU自動完成一部分(例如中斷髮生時、使用TSS),但現代操作系統中,通常由軟件完成。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章