02 CPU上下文切換(上)

2021-10-22 05:40:11 字數 4122 閱讀 1550

cpu上下文切換是什麼意思(上)

1. cpu上下文

我們都知道,linux 是乙個多工作業系統,它支援遠大於 cpu 數量的任務同時執行。當然,這些任務實際上並不是真的在同時執行,而是因為系統在很短的時間內,將 cpu 輪流分配給它們,造成多工同時執行的錯覺。

而在每個任務執行前,cpu 都需要知道任務從**載入、又從**開始執行,也就是說,需要系統事先幫它設定好 cpu上下文。cpu上下文包括了暫存器和程式計數器。

暫存器:是 cpu 內建的容量小、但速度極快的記憶體。

2. cpu上下文切換

cpu 上下文切換,就是先把前乙個任務的 cpu 上下文(也就是 cpu 暫存器和程式計數器)儲存起來,然後載入新任務的cpu上下文,最後再跳轉到程式計數器所指的新位置,執行新任務。

根據任務的不同,cpu 的上下文切換就可以分為幾個不同的場景,也就是程序上下文切換執行緒上下文切換以及中斷上下文切換。

3. 系統呼叫

linux

按照特權等級,把程序的執行空間分為核心空間和使用者空間,分別對應著下圖中,

cpu

特權等級的

ring 0

和ring 3。

核心空間

ring 0

)具有最高許可權,可以直接訪問所有資源;

使用者空間

ring 3

)只能訪問受限資源,不能直接訪問記憶體等硬體裝置,必須通過系統呼叫陷入到核心中,才能訪問這些特權資源。

程序既可以在使用者空間執行,又可以在核心空間中執行。程序在使用者空間執行時,被稱為程序的使用者態,而陷入核心空間的時候,被稱為程序的核心態

從使用者態到核心態的轉變,需要通過系統呼叫來完成。那麼,系統呼叫的過程有沒有發生

cpu

上下文的切換呢?

答案自然是肯定的。

cpu

暫存器裡原來使用者態的指令位置,需要先儲存起來。接著,為了執行核心態**,

cpu

暫存器需要更新為核心態指令的新位置。最後才是跳轉到核心態執行核心任務。而系統呼叫結束後,

cpu

暫存器需要恢復原來儲存的使用者態,然後再切換到使用者空間,繼續執行程序。所以,一次系統呼叫的過程,其實是發生了兩次cpu上下文切換。

不過,需要注意的是:

1)系統呼叫過程中,並不會涉及到虛擬記憶體等程序使用者態的資源,也不會切換程序,所以系統呼叫又稱「特權切換」。

2) 程序上下文切換,是指從乙個程序切換到另乙個程序執行,而系統呼叫過程中一直是同乙個程序在執行。

4. 程序上下文切換

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

cpu

暫存器之前,需要先把該程序的虛擬記憶體、棧等儲存下來;而載入了下一程序的核心態後,還需要重新整理程序的虛擬記憶體和使用者棧。

5. 程序在什麼時候才會被排程到cpu上執行?

其一,為了保證所有程序可以得到公平排程,

cpu

時間被劃分為一段段的時間片,這些時間片再**流分配給各個程序。這樣,當某個程序的時間片耗盡了,就會被系統掛起,切換到其它正在等待

cpu

的程序執行。

其二,程序在系統資源不足(比如記憶體不足)時,要等到資源滿足後才可以執行,這個時候程序也會被掛起,並由系統排程其他程序執行。

其三,當程序通過睡眠函式

sleep

這樣的方法將自己主動掛起時,自然也會重新排程。

其四,當有優先順序更高的程序執行時,為了保證高優先順序程序的執行,當前程序會被掛起,由高優先順序程序來執行。

最後,發生硬體中斷時,

cpu

上的程序會被中斷掛起,轉而執行核心中的中斷服務程式。

6. 執行緒上下文切換

執行緒與程序最大的區別在於,執行緒是排程的基本單位,而程序則是資源擁有的基本單位。說白了,所謂核心中的任務排程,實際上的排程物件是執行緒;而程序只是給執行緒提供了虛擬記憶體、全域性變數等資源。所以,對於執行緒和程序,我們可以這麼理解:

當程序只有乙個執行緒時,可以認為程序就等於執行緒。

當程序擁有多個執行緒時,這些執行緒會共享相同的虛擬記憶體和全域性變數等資源。這些資源在上下文切換時是不需要修改的。

另外,執行緒也有自己的私有資料,比如棧和暫存器等,這些在上下文切換時也是需要儲存的。

這麼一來,執行緒的上下文切換其實就可以分為兩種情況:

第一種,

前後兩個執行緒屬於不同程序。此時,因為資源不共享,所以切換過程就跟程序上下文切換是一樣。

第二種,前後兩個執行緒屬於同乙個程序。此時,因為虛擬記憶體是共享的,所以在切換時,虛擬記憶體這些資源就保持不動,只需要切換執行緒的私有資料、暫存器等不共享的資料。到這裡你應該也發現了,雖然同為上下文切換,但同程序內的執行緒切換,要比多程序間的切換消耗更少的資源,而這,也正是多執行緒代替多程序的乙個優勢。

7. 中斷上下文

中斷是指為了快速響應硬體的事件,會打斷程序的正常排程和執行,轉而呼叫中斷處理程式,響應裝置事件。

跟程序上下文不同,中斷上下文切換並不涉及到程序的使用者態。所以,即便中斷過程打斷了乙個正處在使用者態的程序,也不需要儲存和恢復這個程序的虛擬記憶體、全域性變數等使用者態資源。中斷上下文,中斷上下文只包括核心態中斷服務程式所需的引數,包括cpu暫存器、核心堆疊、硬體中斷引數等

對同乙個cpu來說,中斷處理比程序擁有更高的優先順序,所以中斷上下文切換並不會與程序上下文切換同時發生。同樣道理,由於中斷會打斷正常程序的排程和執行,所以大部分中斷處理程式都短小精悍,以便盡可能快的執行結束。

8. 總結

1、系統呼叫是程序使用者態到核心態的切換,不會涉及程序使用者態資源的修改,比如虛擬記憶體、全域性變數等。系統呼叫發生在同乙個程序內。

2、程序上下文包括了使用者態資源,比如虛擬記憶體、全域性變數等;還包括了核心態資源,比如記憶體堆疊、暫存器。所以,程序上下文切換需要儲存這些資源資訊。

3、執行緒上下文包括了程序使用者態的虛擬記憶體、全域性變數資訊(程序分配的),還有執行緒私有變數比如棧和暫存器。程序內的所有執行緒的使用者態資源是共享的。

4、執行緒上下文切換可以分為下面幾種情況:

(1)同乙個程序內的執行緒切換

使用者態的虛擬記憶體、全域性變數不變,只改變執行緒的私有變數。

(2)不同程序的執行緒切換

等價於程序切換

5、中斷上下文只包括程序核心態中中斷程式所需的資源,比如cpu暫存器、記憶體對戰、中斷引數等。

6、中斷上下文不會和程序上下文切換同時發生,並且中斷上下文切換擁有更高的優先順序。中斷上下文切換也需要消耗

cpu,切換次數過多也會耗費大量的

cpu,甚至嚴重降低系統的整體效能。。

CPU上下文切換(上) malin

cpu上下文切換 我們經常說的平均負載和cpu公升高沒有直接的關係,在不同的場景cpu公升高會導致系統負載,但是系統負載不一定是cpu公升高導致的。一 系統負載過高的三種場景 cpu密集型程序,使用大量cpu會導致平均負載公升高,此時這兩者是一致的。io密集型程序,等待io也會導致平均負載公升高,但...

CPU上下文切換

linux任務執行前,cpu都要知道從任務從 載入 又從 開始執行,也就是說,需要系統事先幫它設定好cpu暫存器和程式計數器 cpu上下文 cpu暫存器和程式計數器 cpu暫存器 cpu內建容量小 速度極快的記憶體 程式計數器 儲存cpu正在執行的指令位置 或者即將執行的下一條指令位置 把前乙個任務...

CPU 上下文切換

乙個酒店,裡面滿滿的客人在吃飯,好比是,酒店裡面的所有人速速離開酒店,讓下一波客人吃。好比是 酒店裡的客人不需要離開酒店,但是服務員就是不給他們上菜,因為服務員去給 vip 客戶服務去了,好在 vip 客戶比較好說話,很快就伺候好了,服務員再來給酒店裡的客人服務 不好意思,這道菜的工序比較複雜,讓您...