小結

總結一下,不管是哪種場景導致的上下文切換,你都應該知道:

  1. CPU 上下文切換,是保證 Linux 系統正常工作的核心功能之一,一般情況下不需要我們特別關注。
  2. 但過多的上下文切換,會把CPU時間消耗在寄存器、內核棧以及虛擬內存等數據的保存和恢復上,從而縮短進程真正運行的時間,導致系統的整體性能大幅下降。

1、多任務競爭CPU,cpu變換任務的時候進行CPU上下文切換(context switch)。CPU執行任務有4種方式:進程、線程、或者硬件通過觸發信號導致中斷的調用。
2、當切換任務的時候,需要記錄任務當前的狀態和獲取下一任務的信息和地址(指針),這就是上下文的內容。因此,上下文是指某一時間點CPU寄存器(CPU register)和程序計數器(PC)的內容, 廣義上還包括內存中進程的虛擬地址映射信息.
3、上下文切換的過程:
(1)記錄當前任務的上下文(即寄存器和計算器等所有的狀態);
(2)找到新任務的上下文並加載;
(3)切換到新任務的程序計算器位置,恢復其任務。
4、根據任務的執行形式,相應的下上文切換,有進程上下文切換、線程上下文切換、以及中斷上下文切換三類。
5、進程和線程的區別:
進程是資源分配和執行的基本單位;線程是任務調度和運行的基本單位。線程沒有資源,進程給指針提供虛擬內存、棧、變量等共享資源,而線程可以共享進程的資源。
6、進程上下文切換:是指從一個進程切換到另一個進程。
(1)進程運行態為內核運行態和進程運行態。內核空間態資源包括內核的堆棧、寄存器等;用户空間態資源包括虛擬內存、棧、變量、正文、數據等
(2)系統調用(軟中斷)在內核態完成的,需要進行2次CPU上下文切換(用户空間-->內核空間-->用户空間),不涉及用户態資源,也不會切換進程。
(3)進程是由內核來管理和調度的,進程的切換隻能發生在內核態。所以,進程的上下文不僅包括了用户空間的資源,也包括內核空間資源。
(4)進程的上下文切換過程:
(a)接收到切換信號,掛起進程,記錄當前進程的虛擬內存、棧等資源存儲;
(b)將這個進程在 CPU 中的上下文狀態存儲於起來;
(c)然後在內存中檢索下一個進程的上下文;
(d)並將其加載到 CPU的寄存器中恢復;
(3)還需要刷新進程的虛擬內存和用户棧;
(f)最後跳轉到程序計數器所指向的位置(即跳轉到進程被中斷時的代碼行),以恢復該進程。
(5)、下列將會觸發進程上下文切換的場景:
(a)、根據調度策略,將CPU時間劃片為對應的時間片,當時間片耗盡,當前進程必須掛起。
(b)、資源不足的,在獲取到足夠資源之前進程掛起。
(c)、進程sleep掛起進程。
(d)、高優先級進程導致當前進度掛起
(e)、硬件中斷,導致當前進程掛起
7、線程上下文切換:
(1)、不通進程之間的線程上下文切換,其過程和進程上下文切換大致相同。
(2)、進程內部的線程進上下文切換。不需要切換進程的用户資源,只需要切換線程私有的數據和寄存器等。這會比進程上下文進程切換消耗的資源少,所以多線程相比多進程的優勢。
8、中斷上下文切換
快速響應硬件的事件,中斷處理會打斷進程的正常調度和執行。同一CPU內,硬件中斷優先級高於進程。切換過程類似於系統調用的時候,不涉及到用户運行態資源。但大量的中斷上下文切換同樣可能引發性能問題。