各個進程之間是共享 CPU 資源的,在不同的時候進程之間需要切換,讓不同的進程可以在 CPU 執行,那么這個一個進程切換到另一個進程運行,稱為進程的上下文切換。
進程是由內核管理和調度的,所以進程的切換只能發生在內核態。
所以,進程的上下文切換不僅包含了虛擬內存、棧、全局變量等用戶空間的資源,還包括了內核堆棧、寄存器等內核空間的資源。
大家需要注意,進程的上下文開銷是很關鍵的,我們希望它的開銷越小越好,這樣可以使得進程可以把更多時間花費在執行程序上,而不是耗費在上下文切換。
發生進程上下文切換有哪些場景?
1. 為了保證所有進程可以得到公平調度,CPU 時間被划分為一段段的時間片,這些時間片再被輪流分配給各個進程。這樣,當某個進程的時間片耗盡了,就會被系統掛起,切換到其它正在等待 CPU 的進程運行;
2. 進程在系統資源不足(比如內存不足)時,要等到資源滿足后才可以運行,這個時候進程也會被掛起,並由系統調度其他進程運行;
3. 當進程通過睡眠函數 sleep 這樣的方法將自己主動掛起時,自然也會重新調度;
4. 當有優先級更高的進程運行時,為了保證高優先級進程的運行,當前進程會被掛起,由高優先級進程來運行;
5. 發生硬件中斷時,CPU 上的進程會被中斷掛起,轉而執行內核中的中斷服務程序;
下面這個進程是php運行的其中存在sleep函數
查看到的進程切換如下
pidstat -w -p 進程PID 1 10
cswch/s 每秒有10次的主動切換 , 耗費資源比較多