關(guān)于上下文切換的幾個(gè)為什么
上下文切換是什么?
CPU 上下文可以理解成CPU寄存器狀態(tài)以及程序計(jì)數(shù)器PC, 這些都是記錄CPU當(dāng)前任務(wù)的狀態(tài)。
CPU 上下文切換會(huì)把當(dāng)前的cpu的上下文保存下來,然后加載新任務(wù)的對(duì)應(yīng)上下文,而這些保存下來的上下文,會(huì)存儲(chǔ)在系統(tǒng)內(nèi)核中,并在任務(wù)重新調(diào)度執(zhí)行時(shí)再次加載進(jìn)來。這樣就能保證任務(wù)原來的狀態(tài)不受影響,讓任務(wù)看起來還是連續(xù)運(yùn)行。
CPU為什么要進(jìn)行上下文切換?
當(dāng)多個(gè)進(jìn)程競爭CPU的時(shí)候,CPU為了保證每個(gè)進(jìn)程能公平被調(diào)度運(yùn)行,采取了處理任務(wù)時(shí)間分片的機(jī)制,
輪流處理多個(gè)進(jìn)程,由于CPU處理速度非???,在人類的感官上認(rèn)為是并行處理,實(shí)際是"偽"并行,
同一時(shí)間只有一個(gè)任務(wù)在運(yùn)行處理
上下文切換主要消耗什么資源,為什么說上下文切換次數(shù)過多不可?。?/h5>
每次上下文切換都需要幾十納秒到到微秒的CPU時(shí)間,這些時(shí)間對(duì)CPU來說,
就好比人類對(duì)1分鐘或10分鐘的感覺概念。在分秒必爭的計(jì)算機(jī)處理環(huán)境下,浪費(fèi)太多時(shí)間在切換上,
只能會(huì)降低真正處理任務(wù)的時(shí)間,表象上導(dǎo)致延時(shí)、排隊(duì)、卡頓現(xiàn)象發(fā)生
上下文切換分幾種?
特權(quán)模式切換、 進(jìn)程上下文切換、線程上下文切換、中斷上下文切換
什么情況下會(huì)觸發(fā)上下文切換?
系統(tǒng)調(diào)用、進(jìn)程狀態(tài)轉(zhuǎn)換(運(yùn)行、就緒、阻塞)、時(shí)間片耗盡、系統(tǒng)資源不足、sleep、優(yōu)先級(jí)調(diào)度、硬件中斷等
線程上下文切換和進(jìn)程上下文切換的最大區(qū)別?
線程是調(diào)度的基本單位,進(jìn)程是資源擁有的基本單位,同屬一個(gè)進(jìn)程的線程,發(fā)生上下文切換,
只切換線程的私有數(shù)據(jù),共享數(shù)據(jù)不變,因此速度非常快
有哪些減少上下文切換的技術(shù)用例?
數(shù)據(jù)庫連接池(復(fù)用連接)、合理設(shè)置應(yīng)用的最大進(jìn)程,線程數(shù)、直接內(nèi)存訪問DMA、零拷貝技術(shù)
上下文切換過程詳解
特權(quán)模式切換
每次上下文切換都需要幾十納秒到到微秒的CPU時(shí)間,這些時(shí)間對(duì)CPU來說,
就好比人類對(duì)1分鐘或10分鐘的感覺概念。在分秒必爭的計(jì)算機(jī)處理環(huán)境下,浪費(fèi)太多時(shí)間在切換上,
只能會(huì)降低真正處理任務(wù)的時(shí)間,表象上導(dǎo)致延時(shí)、排隊(duì)、卡頓現(xiàn)象發(fā)生
特權(quán)模式切換、 進(jìn)程上下文切換、線程上下文切換、中斷上下文切換
系統(tǒng)調(diào)用、進(jìn)程狀態(tài)轉(zhuǎn)換(運(yùn)行、就緒、阻塞)、時(shí)間片耗盡、系統(tǒng)資源不足、sleep、優(yōu)先級(jí)調(diào)度、硬件中斷等
線程是調(diào)度的基本單位,進(jìn)程是資源擁有的基本單位,同屬一個(gè)進(jìn)程的線程,發(fā)生上下文切換,
只切換線程的私有數(shù)據(jù),共享數(shù)據(jù)不變,因此速度非常快
數(shù)據(jù)庫連接池(復(fù)用連接)、合理設(shè)置應(yīng)用的最大進(jìn)程,線程數(shù)、直接內(nèi)存訪問DMA、零拷貝技術(shù)
Linux 按照特權(quán)等級(jí),把進(jìn)程的運(yùn)行空間分為內(nèi)核空間和用戶空間,分別對(duì)應(yīng)著下圖中, CPU 特權(quán)等級(jí)的 Ring 0 和 Ring 3。內(nèi)核空間(Ring 0)具有最高權(quán)限,可以直接訪問所有資源;用戶空間(Ring 3)只能訪問受限資源,不能直接訪問內(nèi)存等硬件設(shè)備,必須通過系統(tǒng)調(diào)用陷入到內(nèi)核中,才能訪問這些特權(quán)資源。

進(jìn)程可以在用戶空間運(yùn)行,也可以在內(nèi)核空間運(yùn)行。當(dāng)調(diào)用open()、read()、write()、close()系統(tǒng)函數(shù), CPU會(huì)保存原來用戶態(tài)的指令位置,然后更新CPU寄存器內(nèi)核態(tài)指令的新位置。最后執(zhí)行內(nèi)核態(tài)函數(shù)。當(dāng)系統(tǒng)調(diào)用結(jié)束后,CPU恢復(fù)原來的用戶態(tài),切換回用戶空間繼續(xù)執(zhí)行進(jìn)程。
可以看到用戶態(tài)->內(nèi)核態(tài), 內(nèi)核態(tài)->用戶態(tài)這兩個(gè)過程總共是產(chǎn)生了兩次CPU上下文切換。不過,需要注意的是,系統(tǒng)調(diào)用過程中,并不會(huì)涉及到虛擬內(nèi)存等進(jìn)程用戶態(tài)的資源。
進(jìn)程上下文切換
進(jìn)程上下文不僅包括了虛擬內(nèi)存、棧、全局變量等用戶空間的資源,還包括了內(nèi)核堆棧、寄存器等內(nèi)核空間的狀態(tài),與系統(tǒng)調(diào)用相比進(jìn)程間的切換還需要把內(nèi)容保存下來

- 觸發(fā)進(jìn)程上下文切換的場景
根據(jù)調(diào)度策略,將CPU時(shí)間劃片為對(duì)應(yīng)的時(shí)間片,當(dāng)時(shí)間片耗盡,當(dāng)前進(jìn)程必須掛起
系統(tǒng)資源不足的,在獲取到足夠資源之前進(jìn)程掛起
當(dāng)進(jìn)程通過睡眠函數(shù)sleep或者sched_yield這樣的方法將自己主動(dòng)掛起時(shí)
高優(yōu)先級(jí)進(jìn)程導(dǎo)致當(dāng)前進(jìn)程掛起
硬件中斷,導(dǎo)致當(dāng)前進(jìn)程掛起,轉(zhuǎn)而執(zhí)行內(nèi)核中的中斷服務(wù)程序
線程上下文切換
- 不同進(jìn)程之間的線程上下文切換,其過程和進(jìn)程上下文切換大致相同。
- 線程內(nèi)部的線程進(jìn)上下文切換。不需要切換進(jìn)程的用戶資源,只需要切換線程私有的數(shù)據(jù)和寄存器等。
這會(huì)比進(jìn)程上下文進(jìn)程切換消耗的資源少,所以多線程相比多進(jìn)程的優(yōu)勢。
中斷上下文切換
為了快速響應(yīng)硬件的事件(如USB接入),中斷處理會(huì)打斷進(jìn)程的正常調(diào)度和執(zhí)行,轉(zhuǎn)而調(diào)用中斷處理程序,
響應(yīng)設(shè)備事件。而打斷其它進(jìn)程執(zhí)行時(shí),需要進(jìn)行上下文切換。中斷事件過多,會(huì)無謂的消耗CPU資源,導(dǎo)致進(jìn)程處理時(shí)間延長。
對(duì)于一個(gè)CPU來說,中斷處理比進(jìn)程擁有更高的優(yōu)先級(jí), 所以中斷上下文切換并不會(huì)與進(jìn)程上下文切換同時(shí)發(fā)生。