程序切換原理

2022-09-20 13:48:10 字數 2028 閱讀 2208

linux是乙個多工作業系統,它支援遠大於cpu核心數的任務同時進行。當然,這些任務並不是真的同時在執行,而是因為系統在很短的時間內,將cpu輪流分配給它們,造成多工同時執行的錯覺。每個任務在執行前,cpu都需要知道任務從哪來載入,又從**開始執行,也就是說,需要事先幫它們設定好cpu暫存器和程式計數器( program counter,pc )。

cpu暫存器:是cpu內建的容量小、但速度快的記憶體,用來臨時存放指令執行執行過程中的運算元和中間(最終)的操作結果。

cpu暫存器和程式計數器是cpu執行任何任務前,必須依賴的環境,也被稱作cpu上下文

把前乙個任務的cpu上下文(cpu暫存器和程式計數器)儲存起來,然後載入新任務的上下文到這些暫存器和程式計數器,最後再跳轉到程式計數器所指的新位置,執行新的任務。而這些儲存下來的上下文,會儲存在系統核心中,並在任務重新排程執行時再次載入進來。這樣就能保證任務原來的狀態不受影響,讓任務看起來還是連續執行。

cpu的上下文切換可以分為幾個不同的場景:程序上下文切換、執行緒上線文切換、中斷上下文切換;

系統呼叫時的切換

linux按照特權等級,把程序的執行空間分為核心空間和使用者空間。一些特殊的操作如呼叫open()開啟檔案等 都需要切換到核心空間執行,使用者空間是沒有許可權呼叫這些的。也就是說,程序既可以在使用者空間執行,又可以在核心空間執行。在使用者空間執行即為使用者態,而陷入核心空間的時候,即為核心態。這種從使用者態切換到核心態時,必須經過系統呼叫來完成。

系統呼叫需要上下文切換。切換時,先儲存cpu暫存器裡原來使用者態的指令位置。接著,為了執行核心態**,cpu暫存器需要更新為核心態執行的新位置。最後才是跳轉到核心態執行核心任務。系統呼叫結束後,cpu暫存器需要恢復原來儲存的使用者態,然後再切換到使用者空間,繼續執行程序。所以一次系統呼叫的過程,其實是發生了兩次cpu上下文切換。

需要注意的是,系統呼叫過程中,並不會涉及到虛擬記憶體等程序使用者態的資源,也不會進行切換程序。這跟我們通常說的程序上下文切換是不一樣的。

所以,系統呼叫過程通常稱為特權模式切換,而不是上下文切換。但實際上,系統呼叫過程中,cpu的上下文切換還是無法避免的。

程序的切換

程序是由核心來管理和排程的,程序的切換只能發生在核心態。所以,程序的上下文不僅包括虛擬記憶體、棧、全域性變數等使用者空間的資源,還包括核心堆疊、暫存器等核心空間的狀態。因此,程序的上下文切換就比系統呼叫時多了一步:在儲存當前程序的核心狀態和cpu暫存器之前,需要先把該程序的虛擬記憶體、棧等儲存下來;而載入了下一程序的核心態後,還需要重新整理程序的虛擬記憶體和使用者棧。

發生程序上下文切換的場景:

程序切換的檢視:

關鍵點:

發生中斷時的儲存現場,將發生中斷時的所有通用暫存器儲存到程序的核心棧,使用struct pt_regs結構。

位址空間切換將程序自己的頁全域性目錄的基位址pgd儲存在ttbr0_le1中,用於mmu的頁表遍歷的起始點。

硬體上下文切換的時候,將此時的呼叫儲存暫存器和pc, sp儲存到struct cpu_context結構中。做好了這幾個儲存工作,當程序再次被排程回來的時候,通過cpu_context中儲存的pc回到了cpu_switch_to的下一條指令繼續執行,而由於cpu_context中儲存的sp導致當前程序回到自己的核心棧,經過一系列的核心棧的出棧處理,最後將原來儲存在pt_regs中的通用暫存器的值恢復到了通用暫存器,這樣程序回到使用者空間就可以繼續沿著被中斷打斷的下一條指令開始執行,使用者棧也回到了被打斷之前的位置,而程序訪問的指令資料做位址轉化(va到pa)也都是從自己的pgd開始進行,一切對使用者來說就好像沒有發生一樣。

總結;程序切換有兩大步驟:位址空間切換和處理器狀態切換(硬體上下文切換)。前者保證了程序回到使用者空間之後能夠訪問到自己的指令和資料(其中包括減小tlb清空的asid機制),後者保證了程序核心棧和執行流的切換,會將當前程序的硬體上下文儲存在程序所管理的一塊記憶體,然後將即將執行的程序的硬體上下文從記憶體中恢復到暫存器,有了這兩步的切換過程保證了程序執行的有條不紊,當然切換的過程是在核心空間完成,這對於程序來說是透明的。

程序切換和執行緒切換

為了控制程序的執行,核心必須有能力掛起正在cpu上執行的程序,並恢復以前掛起的某個程序的執行。這種行為被稱為程序切換 process switch 任務切換 task switch 或上下文切換 content switch 原文 程序切換分兩步 1.切換頁目錄以使用新的位址空間 2.切換核心棧和硬...

程序切換與執行緒切換

原文 為了控制程序的執行,核心必須有能力掛起正在cpu上執行的程序,並恢復以前掛起的某個程序的執行。這種行為被稱為程序切換 process switch 任務切換 task switch 或上下文切換 content switch 程序切換分兩步 1.切換頁目錄以使用新的位址空間 2.切換核心棧和硬...

程序切換與執行緒切換

為了更好的了解上下文切換,需要我們了解虛擬記憶體的概念。虛擬記憶體是作業系統為每個程序提供的一種抽象,每個程序都有屬於自己的 私有的 位址連續的虛擬記憶體,當然我們知道最終程序的資料及 必然要放到物理記憶體上,那麼必須有某種機制能記住虛擬位址空間中的某個資料被放到了哪個物理記憶體位址上,這就是所謂的...