成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

解鎖CPU上下文切換:深入理解計(jì)算機(jī)的“幕后舞者”

存儲(chǔ) 存儲(chǔ)架構(gòu)
在計(jì)算機(jī)中,CPU 上下文是指 CPU 在執(zhí)行任務(wù)時(shí)所需要的運(yùn)行環(huán)境,包括 CPU 寄存器和程序計(jì)數(shù)器等。CPU 寄存器是 CPU 內(nèi)部的高速存儲(chǔ)單元,用于暫存指令、數(shù)據(jù)和地址等信息 。

在計(jì)算機(jī)的世界里,CPU(Central Processing Unit,中央處理器)無(wú)疑占據(jù)著核心地位,堪稱計(jì)算機(jī)的 “心臟” 。它負(fù)責(zé)執(zhí)行計(jì)算機(jī)程序中的指令,進(jìn)行各種數(shù)學(xué)和邏輯運(yùn)算,控制和協(xié)調(diào)計(jì)算機(jī)的各個(gè)部件,就像人的大腦一樣,指揮著整個(gè)計(jì)算機(jī)系統(tǒng)的運(yùn)作。

當(dāng)我們打開(kāi)電腦,運(yùn)行各種軟件,如辦公軟件處理文檔、瀏覽器瀏覽網(wǎng)頁(yè)、游戲運(yùn)行精彩的畫面,這背后都是 CPU 在辛勤工作。它從內(nèi)存中讀取指令和數(shù)據(jù),對(duì)指令進(jìn)行譯碼,然后執(zhí)行相應(yīng)的操作,再將處理結(jié)果寫回內(nèi)存或輸出給外部設(shè)備。可以說(shuō),CPU 的性能直接決定了計(jì)算機(jī)的運(yùn)行速度和處理能力,影響著我們使用計(jì)算機(jī)時(shí)的體驗(yàn)。

在早期的計(jì)算機(jī)中,CPU 的功能相對(duì)簡(jiǎn)單,性能也較弱。隨著科技的飛速發(fā)展,CPU 不斷進(jìn)化,從最初的單核到如今的多核,主頻越來(lái)越高,緩存越來(lái)越大,指令集也越來(lái)越豐富,能夠應(yīng)對(duì)日益復(fù)雜的計(jì)算任務(wù)和多樣化的應(yīng)用場(chǎng)景 。

一、什么是CPU上下文切換

在計(jì)算機(jī)中,CPU 上下文是指 CPU 在執(zhí)行任務(wù)時(shí)所需要的運(yùn)行環(huán)境,包括 CPU 寄存器和程序計(jì)數(shù)器等。CPU 寄存器是 CPU 內(nèi)部的高速存儲(chǔ)單元,用于暫存指令、數(shù)據(jù)和地址等信息 。程序計(jì)數(shù)器則是用于存儲(chǔ)下一條要執(zhí)行的指令的地址,它就像是一個(gè)導(dǎo)航儀,指引著 CPU 按照正確的順序執(zhí)行程序中的指令。當(dāng) CPU 執(zhí)行一個(gè)任務(wù)時(shí),這些寄存器和程序計(jì)數(shù)器會(huì)被設(shè)置為特定的值,以確保任務(wù)能夠正確運(yùn)行。而這些值的集合,就構(gòu)成了 CPU 上下文,它是任務(wù)運(yùn)行的基礎(chǔ)環(huán)境。

1.1CPU 上下文的構(gòu)成

在理解 CPU 上下文切換之前,我們先來(lái)認(rèn)識(shí)一下 CPU 上下文。CPU 上下文其實(shí)就是 CPU 在執(zhí)行某個(gè)任務(wù)時(shí),所需要的運(yùn)行環(huán)境和狀態(tài)信息。它主要包括以下幾個(gè)關(guān)鍵部分:

  • 寄存器:寄存器是 CPU 內(nèi)置的容量小、但速度極快的內(nèi)存,用于存儲(chǔ)臨時(shí)數(shù)據(jù)和指令的結(jié)果。比如通用寄存器,可用來(lái)保存操作數(shù)、運(yùn)算結(jié)果等 ,像執(zhí)行加法運(yùn)算時(shí),兩個(gè)操作數(shù)可能就暫存在通用寄存器中。程序計(jì)數(shù)器(PC),它時(shí)刻記錄著 CPU 即將執(zhí)行的下一條指令的內(nèi)存地址,如同一個(gè)導(dǎo)航,指引著 CPU 按順序執(zhí)行程序指令。堆棧指針(SP),指向當(dāng)前堆棧的頂部,在函數(shù)調(diào)用、返回等操作中,用于管理堆棧,保存和恢復(fù)函數(shù)的局部變量、返回地址等信息。狀態(tài)寄存器 / 標(biāo)志寄存器,則保存了關(guān)于最近操作的狀態(tài)信息,例如零標(biāo)志(用于判斷運(yùn)算結(jié)果是否為 0)、符號(hào)標(biāo)志(表示結(jié)果的正負(fù))、溢出標(biāo)志(判斷運(yùn)算是否產(chǎn)生溢出)等。這些標(biāo)志位對(duì)于程序的流程控制,如條件判斷、分支跳轉(zhuǎn)等操作至關(guān)重要。
  • 內(nèi)存管理信息:這部分包含了內(nèi)存分配的相關(guān)信息,比如頁(yè)表或段表的信息。頁(yè)表用于實(shí)現(xiàn)虛擬內(nèi)存到物理內(nèi)存的映射,當(dāng) CPU 訪問(wèn)內(nèi)存時(shí),通過(guò)頁(yè)表將虛擬地址轉(zhuǎn)換為物理地址,從而找到實(shí)際的數(shù)據(jù)或指令存儲(chǔ)位置,同時(shí)也起到了內(nèi)存保護(hù)的作用,防止不同進(jìn)程非法訪問(wèn)彼此的內(nèi)存空間。
  • 進(jìn)程控制塊(PCB):操作系統(tǒng)為每個(gè)進(jìn)程維護(hù)的數(shù)據(jù)結(jié)構(gòu),里面包含了進(jìn)程的各種重要信息,如進(jìn)程的狀態(tài)(運(yùn)行、就緒、阻塞等)、程序計(jì)數(shù)器的值、寄存器集合、內(nèi)存管理信息等。PCB 就像是進(jìn)程的 “身份證”,記錄了進(jìn)程運(yùn)行所需的全部上下文信息,操作系統(tǒng)通過(guò) PCB 來(lái)管理和調(diào)度進(jìn)程 。

1.2CPU 上下文切換的過(guò)程

當(dāng) CPU 需要從一個(gè)任務(wù)切換到另一個(gè)任務(wù)時(shí),就會(huì)發(fā)生上下文切換。這個(gè)過(guò)程主要包括以下幾個(gè)步驟:

  • 保存前一個(gè)任務(wù)的上下文:CPU 會(huì)將當(dāng)前任務(wù)的 CPU 寄存器和程序計(jì)數(shù)器中的值保存到內(nèi)存中,通常是保存在該任務(wù)對(duì)應(yīng)的進(jìn)程控制塊(PCB)或線程控制塊(TCB)中。這樣,當(dāng)該任務(wù)再次被調(diào)度執(zhí)行時(shí),就可以從這些保存的值中恢復(fù)到之前的運(yùn)行狀態(tài)。就加載新任務(wù)的上下文:從內(nèi)存中讀取下一個(gè)要執(zhí)行任務(wù)的上下文信息,將其加載到 CPU 寄存器和程序計(jì)數(shù)器中。這些信息告訴 CPU 新任務(wù)的指令和數(shù)據(jù)存儲(chǔ)在哪里,以及從哪里開(kāi)始執(zhí)行新任務(wù)。
  • 跳轉(zhuǎn)執(zhí)行新任務(wù):CPU 根據(jù)加載的程序計(jì)數(shù)器的值,跳轉(zhuǎn)到新任務(wù)的起始地址,開(kāi)始執(zhí)行新任務(wù)的指令 。

1.3上下文切換的定義

當(dāng)操作系統(tǒng)需要在多個(gè)任務(wù)(進(jìn)程或線程)之間切換 CPU 的控制權(quán)時(shí),就會(huì)發(fā)生 CPU 上下文切換。簡(jiǎn)單來(lái)說(shuō),上下文切換就是把當(dāng)前正在執(zhí)行任務(wù)的 CPU 上下文(寄存器狀態(tài)、程序計(jì)數(shù)器等信息)保存起來(lái),然后加載下一個(gè)要執(zhí)行任務(wù)的 CPU 上下文到寄存器和程序計(jì)數(shù)器中,最后跳轉(zhuǎn)到新任務(wù)的程序計(jì)數(shù)器所指的位置,開(kāi)始執(zhí)行新任務(wù) 。

這一過(guò)程類似于我們?cè)谧龆囗?xiàng)任務(wù)時(shí)的切換。比如,你正在寫一篇文章,突然電話響了,你需要暫停寫作,記錄下寫到哪里了(保存當(dāng)前上下文),然后去接電話(切換到新任務(wù))。接完電話后,你再根據(jù)之前記錄的信息,回到文章的寫作中(加載之前保存的上下文并繼續(xù)執(zhí)行) 。在計(jì)算機(jī)中,上下文切換使得 CPU 能夠在多個(gè)任務(wù)之間快速切換,看似同時(shí)執(zhí)行多個(gè)任務(wù),實(shí)現(xiàn)多任務(wù)并發(fā)執(zhí)行的效果,提高了系統(tǒng)的資源利用率和響應(yīng)速度 。但上下文切換也并非毫無(wú)代價(jià),每次切換都需要消耗一定的 CPU 時(shí)間和資源,頻繁的上下文切換可能會(huì)對(duì)系統(tǒng)性能產(chǎn)生負(fù)面影響。

二、CPU 上下文切換的類型

根據(jù)任務(wù)類型和切換場(chǎng)景的不同,CPU 上下文切換主要分為進(jìn)程上下文切換、線程上下文切換和中斷上下文切換這三種類型。接下來(lái),讓我們深入了解一下它們各自的特點(diǎn)和工作機(jī)制。

2.1進(jìn)程上下文切換

(1)線程與進(jìn)程的關(guān)系

線程是進(jìn)程的一個(gè)實(shí)體,是 CPU 調(diào)度和分派的基本單位 ,它比進(jìn)程更小,能獨(dú)立運(yùn)行。一個(gè)進(jìn)程可以包含多個(gè)線程,這些線程共享所屬進(jìn)程的資源,如地址空間、代碼段、數(shù)據(jù)段和打開(kāi)的文件等 。但每個(gè)線程有自己獨(dú)立的棧空間、程序計(jì)數(shù)器和寄存器集合,用于保存線程運(yùn)行時(shí)的狀態(tài)和局部變量等信息。打個(gè)比方,進(jìn)程就像是一個(gè)工廠,它擁有各種生產(chǎn)設(shè)備、原材料等資源,而線程則像是工廠里的工人,每個(gè)工人都在這個(gè)工廠里工作,共享工廠的資源,但每個(gè)工人有自己的工作流程和工具(棧和寄存器等) 。

(2)進(jìn)程運(yùn)行空間

進(jìn)程在運(yùn)行過(guò)程中存在兩種狀態(tài):用戶態(tài)和內(nèi)核態(tài)。當(dāng)進(jìn)程運(yùn)行在用戶態(tài)時(shí),它只能執(zhí)行非特權(quán)指令,訪問(wèn)受限的內(nèi)存空間,主要用于執(zhí)行用戶程序的代碼,這就像是一個(gè)在自己房間里活動(dòng)的人,只能使用房間內(nèi)允許使用的物品 。而內(nèi)核態(tài)則擁有更高的權(quán)限,可以執(zhí)行特權(quán)指令,訪問(wèn)系統(tǒng)的所有資源,包括硬件設(shè)備等,相當(dāng)于這個(gè)人擁有了進(jìn)入整個(gè)房子所有房間的權(quán)限,能操作各種關(guān)鍵設(shè)備和資源。

與之對(duì)應(yīng)的是,內(nèi)存空間被劃分為內(nèi)核空間和用戶空間。內(nèi)核空間是操作系統(tǒng)內(nèi)核運(yùn)行的區(qū)域,存儲(chǔ)著內(nèi)核代碼和數(shù)據(jù)結(jié)構(gòu),所有進(jìn)程共享這部分空間,用于執(zhí)行關(guān)鍵的系統(tǒng)任務(wù),如進(jìn)程調(diào)度、內(nèi)存管理、設(shè)備驅(qū)動(dòng)等 。用戶空間則是每個(gè)進(jìn)程私有的,用于存放進(jìn)程的代碼、數(shù)據(jù)、堆棧等,不同進(jìn)程的用戶空間相互隔離,保證了進(jìn)程之間的獨(dú)立性和安全性,就像每個(gè)進(jìn)程都有自己獨(dú)立的 “小天地” 。

(3)切換過(guò)程與開(kāi)銷

進(jìn)程上下文切換的過(guò)程較為復(fù)雜。當(dāng)從一個(gè)進(jìn)程切換到另一個(gè)進(jìn)程時(shí),操作系統(tǒng)首先要保存當(dāng)前進(jìn)程在用戶態(tài)下的資源,如虛擬內(nèi)存的映射關(guān)系(通過(guò)頁(yè)表記錄虛擬地址到物理地址的轉(zhuǎn)換信息)、棧(保存函數(shù)調(diào)用的局部變量、返回地址等)、全局變量等 。這些信息是進(jìn)程在用戶態(tài)執(zhí)行的關(guān)鍵數(shù)據(jù),保存起來(lái)以便下次恢復(fù)執(zhí)行。

接著,保存內(nèi)核態(tài)的資源,包括內(nèi)核堆棧(用于內(nèi)核函數(shù)調(diào)用時(shí)保存信息)、寄存器(如通用寄存器保存運(yùn)算數(shù)據(jù)、程序計(jì)數(shù)器指示下一條要執(zhí)行的指令地址等) 。完成保存后,加載下一個(gè)進(jìn)程的內(nèi)核態(tài)資源到寄存器和內(nèi)核堆棧中,設(shè)置好新的程序計(jì)數(shù)器,指向新進(jìn)程要執(zhí)行的起始指令地址。最后,加載新進(jìn)程的用戶態(tài)資源,更新虛擬內(nèi)存映射,恢復(fù)棧和全局變量等 。

這個(gè)過(guò)程需要消耗一定的 CPU 時(shí)間和資源,因?yàn)樯婕暗酱罅繑?shù)據(jù)的保存和加載。頻繁的進(jìn)程上下文切換會(huì)導(dǎo)致 CPU 花費(fèi)較多時(shí)間在這些操作上,從而減少了真正用于執(zhí)行進(jìn)程任務(wù)的時(shí)間,降低系統(tǒng)的整體性能。

(4)線程上下文切換的場(chǎng)景

時(shí)間片耗盡:操作系統(tǒng)采用時(shí)間片輪轉(zhuǎn)調(diào)度算法,為每個(gè)線程分配一定的時(shí)間片。當(dāng)線程的時(shí)間片用完時(shí),即使該線程的任務(wù)尚未完成,操作系統(tǒng)也會(huì)暫停當(dāng)前線程的執(zhí)行,將其狀態(tài)保存起來(lái),并從就緒隊(duì)列中選擇另一個(gè)線程執(zhí)行,從而發(fā)生線程上下文切換 。例如,在一個(gè)多線程的 Web 服務(wù)器中,每個(gè)處理客戶端請(qǐng)求的線程被分配 10 毫秒的時(shí)間片,當(dāng)某個(gè)線程處理一個(gè)較大的請(qǐng)求,10 毫秒內(nèi)無(wú)法完成時(shí),就會(huì)被切換出去。

線程阻塞:當(dāng)線程執(zhí)行 I/O 操作(如讀取文件、網(wǎng)絡(luò)通信)、等待獲取鎖資源、調(diào)用 sleep () 或 wait () 等方法時(shí),會(huì)主動(dòng)將自己阻塞,讓出 CPU 資源 。此時(shí),操作系統(tǒng)會(huì)調(diào)度其他就緒的線程運(yùn)行,導(dǎo)致線程上下文切換。比如在一個(gè)數(shù)據(jù)庫(kù)訪問(wèn)程序中,線程需要從數(shù)據(jù)庫(kù)中讀取大量數(shù)據(jù),在等待數(shù)據(jù)返回的過(guò)程中,線程會(huì)被阻塞,操作系統(tǒng)會(huì)切換到其他線程執(zhí)行。

高優(yōu)先級(jí)線程搶占:如果系統(tǒng)中存在優(yōu)先級(jí)更高的線程進(jìn)入就緒狀態(tài),為了保證高優(yōu)先級(jí)線程能夠及時(shí)得到執(zhí)行,操作系統(tǒng)可能會(huì)立即暫停當(dāng)前正在運(yùn)行的低優(yōu)先級(jí)線程,將 CPU 資源分配給高優(yōu)先級(jí)線程,引發(fā)線程上下文切換 。例如,在一個(gè)實(shí)時(shí)監(jiān)控系統(tǒng)中,處理緊急警報(bào)的線程具有較高的優(yōu)先級(jí),一旦有警報(bào)產(chǎn)生,該線程會(huì)搶占其他低優(yōu)先級(jí)線程的 CPU 資源。

(5)線程上下文切換的開(kāi)銷與優(yōu)化

線程上下文切換雖然比進(jìn)程上下文切換開(kāi)銷小,但也會(huì)帶來(lái)一定的時(shí)間和資源消耗。在切換過(guò)程中,需要保存和恢復(fù)線程的寄存器狀態(tài)、程序計(jì)數(shù)器、棧指針等信息,這需要 CPU 執(zhí)行額外的指令 。頻繁的線程上下文切換還可能導(dǎo)致 CPU 緩存失效,因?yàn)榍袚Q后新線程訪問(wèn)的數(shù)據(jù)可能不在當(dāng)前的 CPU 緩存中,從而增加內(nèi)存訪問(wèn)的延遲,降低系統(tǒng)性能 。為了減少線程上下文切換帶來(lái)的開(kāi)銷,可以采取以下優(yōu)化策略:

  • 使用線程池:線程池可以復(fù)用已創(chuàng)建的線程,避免頻繁創(chuàng)建和銷毀線程,從而減少線程上下文切換的次數(shù) 。例如,在一個(gè)高并發(fā)的 Web 應(yīng)用中,使用線程池來(lái)處理用戶請(qǐng)求,線程池中的線程在完成一個(gè)請(qǐng)求后,不會(huì)被銷毀,而是繼續(xù)處理下一個(gè)請(qǐng)求,大大提高了系統(tǒng)的性能。
  • 減少鎖競(jìng)爭(zhēng):鎖競(jìng)爭(zhēng)是導(dǎo)致線程阻塞和上下文切換的常見(jiàn)原因之一。通過(guò)優(yōu)化鎖的使用,如減小鎖的粒度、縮短鎖的持有時(shí)間、使用讀寫鎖代替獨(dú)占鎖等,可以減少線程之間的競(jìng)爭(zhēng),降低線程阻塞的概率,進(jìn)而減少線程上下文切換 。比如在一個(gè)多線程訪問(wèn)的緩存系統(tǒng)中,使用讀寫鎖,讀操作時(shí)多個(gè)線程可以同時(shí)獲取讀鎖,而寫操作時(shí)才需要獲取獨(dú)占的寫鎖,這樣可以提高系統(tǒng)的并發(fā)性能。
  • 合理設(shè)置線程數(shù)量:根據(jù)系統(tǒng)的 CPU 核心數(shù)、任務(wù)類型(CPU 密集型或 I/O 密集型)等因素,合理設(shè)置線程的數(shù)量,避免創(chuàng)建過(guò)多的線程 。過(guò)多的線程會(huì)導(dǎo)致 CPU 在多個(gè)線程之間頻繁切換,反而降低系統(tǒng)的整體性能。一般來(lái)說(shuō),對(duì)于 CPU 密集型任務(wù),線程數(shù)量可以設(shè)置為 CPU 核心數(shù)加 1;對(duì)于 I/O 密集型任務(wù),線程數(shù)量可以適當(dāng)增加,例如設(shè)置為 CPU 核心數(shù)的 2 倍或更多,但具體數(shù)值需要通過(guò)測(cè)試來(lái)確定 。

2.2線程上下文切換

(1)線程與進(jìn)程的區(qū)別

線程是進(jìn)程內(nèi)的一個(gè)執(zhí)行單元,是操作系統(tǒng)進(jìn)行 CPU 調(diào)度的基本單位 。而進(jìn)程是資源分配的基本單位,擁有獨(dú)立的地址空間、內(nèi)存、文件句柄、信號(hào)處理器等系統(tǒng)資源 。一個(gè)進(jìn)程可以包含多個(gè)線程,這些線程共享所屬進(jìn)程的資源,如代碼段、數(shù)據(jù)段、堆、文件描述符等 。就好比一個(gè)公司是一個(gè)進(jìn)程,公司里的各個(gè)部門就是線程,各個(gè)部門共享公司的辦公場(chǎng)地、設(shè)備等資源,但每個(gè)部門有自己的工作流程和任務(wù) 。線程的創(chuàng)建、銷毀和切換開(kāi)銷相對(duì)較小,因?yàn)樗恍枰襁M(jìn)程那樣分配和管理大量的資源,這使得線程在實(shí)現(xiàn)多任務(wù)并發(fā)時(shí)更加高效和靈活 。

(2)同進(jìn)程線程切換

在同一個(gè)進(jìn)程內(nèi),線程之間的上下文切換相對(duì)簡(jiǎn)單 。由于它們共享進(jìn)程的資源,如虛擬內(nèi)存、全局變量等,所以在切換時(shí),這些共享資源不需要重新加載和切換 。只需要切換線程私有的數(shù)據(jù),主要是寄存器(每個(gè)線程有自己獨(dú)立的寄存器狀態(tài),用于保存線程執(zhí)行過(guò)程中的臨時(shí)數(shù)據(jù)、指令指針等)和棧(線程的棧用于存儲(chǔ)函數(shù)調(diào)用的局部變量、返回地址等,每個(gè)線程也有自己獨(dú)立的棧空間) ;這種切換方式開(kāi)銷較小,速度較快,就像在一個(gè)房間里,不同的人(線程)輪流使用相同的工具(共享資源),只需要更換一下個(gè)人使用的小物品(私有數(shù)據(jù))即可 。

(3)不同進(jìn)程線程切換

如果線程屬于不同的進(jìn)程,那么它們之間的上下文切換過(guò)程就和進(jìn)程上下文切換基本一致 。因?yàn)椴煌M(jìn)程的線程擁有不同的進(jìn)程資源,包括獨(dú)立的虛擬內(nèi)存空間、文件描述符等 。在切換時(shí),不僅要切換線程的私有數(shù)據(jù),如寄存器和棧,還需要切換進(jìn)程的資源,如虛擬內(nèi)存映射、全局變量等 。這就好比從一個(gè)房間(進(jìn)程)到另一個(gè)房間(進(jìn)程),不僅要更換個(gè)人使用的小物品(私有數(shù)據(jù)),還要更換整個(gè)房間的工具和環(huán)境(進(jìn)程資源) ,所以開(kāi)銷相對(duì)較大 。

2.3中斷上下文切換

中斷是計(jì)算機(jī)系統(tǒng)中一種重要的機(jī)制,它允許硬件設(shè)備(如網(wǎng)卡、硬盤、鍵盤等)在需要時(shí)向 CPU 發(fā)送信號(hào),通知 CPU 有緊急事件需要處理 。當(dāng) CPU 接收到中斷信號(hào)時(shí),會(huì)暫停當(dāng)前正在執(zhí)行的任務(wù),轉(zhuǎn)而執(zhí)行專門的中斷處理程序來(lái)響應(yīng)這個(gè)事件 。例如,當(dāng)網(wǎng)卡接收到網(wǎng)絡(luò)數(shù)據(jù)時(shí),會(huì)向 CPU 發(fā)送中斷信號(hào),CPU 暫停當(dāng)前進(jìn)程的執(zhí)行,調(diào)用網(wǎng)卡的中斷處理程序,將接收到的數(shù)據(jù)讀取到內(nèi)存中,然后再返回原來(lái)的進(jìn)程繼續(xù)執(zhí)行。中斷的作用主要有以下幾點(diǎn):

  • 提高 CPU 效率:在沒(méi)有中斷機(jī)制的情況下,CPU 需要不斷地查詢硬件設(shè)備的狀態(tài),以確定是否有數(shù)據(jù)需要處理,這會(huì)浪費(fèi)大量的 CPU 時(shí)間 。而中斷機(jī)制使得 CPU 可以專注于執(zhí)行當(dāng)前任務(wù),只有當(dāng)硬件設(shè)備有數(shù)據(jù)需要處理時(shí)才會(huì)被中斷,從而大大提高了 CPU 的利用率 。
  • 實(shí)現(xiàn)實(shí)時(shí)響應(yīng):對(duì)于一些實(shí)時(shí)性要求較高的應(yīng)用場(chǎng)景,如工業(yè)控制、航空航天等,需要及時(shí)響應(yīng)外部設(shè)備的事件 。中斷機(jī)制可以確保 CPU 能夠在最短的時(shí)間內(nèi)對(duì)這些事件做出響應(yīng),保證系統(tǒng)的實(shí)時(shí)性和穩(wěn)定性 。
  • 支持多任務(wù)處理:中斷機(jī)制是實(shí)現(xiàn)多任務(wù)處理的基礎(chǔ)之一。通過(guò)中斷,操作系統(tǒng)可以在不同任務(wù)之間進(jìn)行切換,實(shí)現(xiàn)多個(gè)任務(wù)的并發(fā)執(zhí)行 。例如,當(dāng)一個(gè)任務(wù)進(jìn)行 I/O 操作時(shí),CPU 可以通過(guò)中斷切換到其他任務(wù)執(zhí)行,提高系統(tǒng)的整體性能 。

當(dāng)硬件設(shè)備產(chǎn)生中斷信號(hào)時(shí),中斷上下文切換的過(guò)程如下:

  • 保存當(dāng)前進(jìn)程狀態(tài):CPU 接收到中斷信號(hào)后,首先會(huì)保存當(dāng)前正在執(zhí)行進(jìn)程的 CPU 寄存器、程序計(jì)數(shù)器等狀態(tài)信息,這些信息被保存在內(nèi)核堆棧中 。這樣,當(dāng)處理完中斷后,能夠恢復(fù)到原來(lái)進(jìn)程的執(zhí)行狀態(tài)。
  • 識(shí)別中斷源:CPU 通過(guò)中斷控制器獲取中斷向量,根據(jù)中斷向量在中斷描述符表(IDT)中查找對(duì)應(yīng)的中斷處理程序的入口地址 。不同的硬件設(shè)備對(duì)應(yīng)不同的中斷向量,通過(guò)這種方式可以確定是哪個(gè)設(shè)備產(chǎn)生了中斷。
  • 切換到中斷處理程序:CPU 跳轉(zhuǎn)到中斷處理程序的入口地址,開(kāi)始執(zhí)行中斷處理程序 。在這個(gè)過(guò)程中,CPU 會(huì)切換到內(nèi)核態(tài),因?yàn)橹袛嗵幚沓绦蛲ǔ_\(yùn)行在內(nèi)核空間,具有更高的權(quán)限,可以直接訪問(wèn)硬件資源 。
  • 執(zhí)行中斷處理:中斷處理程序根據(jù)中斷源的類型,執(zhí)行相應(yīng)的處理操作 。例如,如果是網(wǎng)卡中斷,中斷處理程序會(huì)讀取網(wǎng)卡接收到的數(shù)據(jù),并將其存儲(chǔ)到內(nèi)存中;如果是定時(shí)器中斷,中斷處理程序可能會(huì)更新系統(tǒng)時(shí)間,或者進(jìn)行任務(wù)調(diào)度 。
  • 恢復(fù)進(jìn)程狀態(tài):中斷處理程序執(zhí)行完畢后,會(huì)從內(nèi)核堆棧中恢復(fù)之前保存的進(jìn)程狀態(tài)信息,包括 CPU 寄存器、程序計(jì)數(shù)器等 。然后,CPU 返回到原來(lái)被中斷的進(jìn)程,繼續(xù)執(zhí)行該進(jìn)程的指令 。

中斷上下文切換與進(jìn)程、線程上下文切換存在以下明顯區(qū)別:

涉及的資源不同:進(jìn)程上下文切換不僅要保存和恢復(fù)用戶空間的資源(如虛擬內(nèi)存、棧、全局變量等),還要保存和恢復(fù)內(nèi)核空間的狀態(tài)(如內(nèi)核堆棧、寄存器等);線程上下文切換,如果是同一進(jìn)程內(nèi)的線程切換,只需要切換線程的私有數(shù)據(jù)(如棧和寄存器等),而共享的進(jìn)程資源不需要切換,如果是不同進(jìn)程間的線程切換,過(guò)程和進(jìn)程上下文切換類似;而中斷上下文切換不涉及進(jìn)程的用戶態(tài)資源,只需要保存和恢復(fù)內(nèi)核態(tài)中斷服務(wù)程序執(zhí)行所必需的狀態(tài),如 CPU寄存器、內(nèi)核堆棧、硬件中斷參數(shù)等 。
 優(yōu)先級(jí)不同:中斷具有最高的優(yōu)先級(jí),當(dāng)中斷發(fā)生時(shí),會(huì)立即打斷當(dāng)前正在執(zhí)行的進(jìn)程或線程,優(yōu)先處理中斷 。而進(jìn)程和線程之間的上下文切換是根據(jù)調(diào)度算法進(jìn)行的,優(yōu)先級(jí)相對(duì)較低 。例如,在一個(gè)實(shí)時(shí)系統(tǒng)中,當(dāng)有緊急的硬件事件產(chǎn)生中斷時(shí),即使當(dāng)前有高優(yōu)先級(jí)的進(jìn)程正在運(yùn)行,也會(huì)被中斷,轉(zhuǎn)而處理中斷事件 。
 觸發(fā)原因不同:進(jìn)程上下文切換通常是由進(jìn)程調(diào)度器根據(jù)時(shí)間片耗盡、資源不足、進(jìn)程主動(dòng)掛起等原因觸發(fā);線程上下文切換通常是由線程調(diào)度器根據(jù)線程的執(zhí)行狀態(tài)(如時(shí)間片耗盡、線程阻塞、高優(yōu)先級(jí)線程搶占等)觸發(fā);而中斷上下文切換是由硬件設(shè)備產(chǎn)生的中斷信號(hào)觸發(fā),是異步發(fā)生的,與進(jìn)程和線程的執(zhí)行狀態(tài)無(wú)關(guān) 。例如,當(dāng)鍵盤有按鍵按下時(shí),會(huì)產(chǎn)生一個(gè)硬件中斷,觸發(fā)中斷上下文切換,而不管當(dāng)前系統(tǒng)中進(jìn)程和線程的運(yùn)行情況 。
 切換時(shí)機(jī)不同:中斷上下文切換可以在任何時(shí)刻發(fā)生,只要有硬件中斷信號(hào)產(chǎn)生;而進(jìn)程上下文切換和線程上下文切換通常發(fā)生在操作系統(tǒng)進(jìn)行調(diào)度決策時(shí),例如進(jìn)程時(shí)間片用完或者線程主動(dòng)放棄 CPU 時(shí) 。此外,中斷上下文切換不會(huì)與進(jìn)程上下文切換同時(shí)發(fā)生,因?yàn)橹袛嗵幚砭哂懈叩膬?yōu)先級(jí),會(huì)優(yōu)先執(zhí)行中斷處理程序,處理完中斷后才會(huì)恢復(fù)進(jìn)程的執(zhí)行。

三、頻繁上下文切換的影響

盡管上下文切換是多任務(wù)操作系統(tǒng)實(shí)現(xiàn)并發(fā)執(zhí)行的關(guān)鍵機(jī)制,但頻繁的上下文切換會(huì)給系統(tǒng)性能帶來(lái)一系列負(fù)面影響。

3.1CPU 資源浪費(fèi)

每次上下文切換都需要花費(fèi)一定的 CPU 時(shí)間來(lái)保存當(dāng)前任務(wù)的上下文信息,包括寄存器狀態(tài)、程序計(jì)數(shù)器、內(nèi)存管理信息等,然后再加載下一個(gè)任務(wù)的上下文信息 。這些操作本身并不執(zhí)行實(shí)際的任務(wù)計(jì)算,屬于額外的開(kāi)銷 。如果上下文切換過(guò)于頻繁,CPU 將大部分時(shí)間消耗在這些保存和恢復(fù)上下文的操作上,真正用于執(zhí)行任務(wù)的時(shí)間就會(huì)減少,導(dǎo)致 CPU 的實(shí)際使用率降低 。打個(gè)比方,一個(gè)工廠原本專注于生產(chǎn)產(chǎn)品,但如果頻繁地在不同生產(chǎn)線之間切換,花費(fèi)大量時(shí)間準(zhǔn)備和調(diào)整設(shè)備,那么實(shí)際用于生產(chǎn)產(chǎn)品的時(shí)間就會(huì)減少,生產(chǎn)效率也會(huì)隨之下降 。

3.2緩存失效

CPU緩存是為了提高CPU訪問(wèn)內(nèi)存數(shù)據(jù)的速度而設(shè)計(jì)的,它保存了最近訪問(wèn)的內(nèi)存數(shù)據(jù)和指令 。在上下文切換時(shí),由于新任務(wù)訪問(wèn)的數(shù)據(jù)和指令與原任務(wù)可能不同,原任務(wù)在 CPU 緩存中的數(shù)據(jù)對(duì)于新任務(wù)來(lái)說(shuō)很可能不再有用,導(dǎo)致緩存失效 。新任務(wù)需要重新從內(nèi)存中讀取數(shù)據(jù)和指令,填充緩存,這個(gè)過(guò)程會(huì)增加內(nèi)存訪問(wèn)延遲 。例如,你正在使用瀏覽器瀏覽網(wǎng)頁(yè),此時(shí)瀏覽器進(jìn)程在 CPU 上運(yùn)行,其相關(guān)的數(shù)據(jù)和指令被緩存到 CPU 緩存中。當(dāng)發(fā)生上下文切換,切換到一個(gè)視頻播放進(jìn)程時(shí),瀏覽器進(jìn)程在緩存中的數(shù)據(jù)對(duì)于視頻播放進(jìn)程來(lái)說(shuō)大多無(wú)用,視頻播放進(jìn)程需要重新從內(nèi)存讀取自己所需的數(shù)據(jù)和指令,這就增加了獲取數(shù)據(jù)的時(shí)間,影響了系統(tǒng)的響應(yīng)速度 。

3.3任務(wù)延遲與吞吐量降低

頻繁的上下文切換使得任務(wù)不能持續(xù)地在 CPU 上執(zhí)行,而是不斷地被暫停和重新調(diào)度 。每個(gè)任務(wù)都需要等待輪到自己執(zhí)行,這就導(dǎo)致任務(wù)的執(zhí)行時(shí)間變長(zhǎng),產(chǎn)生延遲 。從系統(tǒng)整體來(lái)看,由于 CPU 在多個(gè)任務(wù)之間頻繁切換,無(wú)法高效地處理每個(gè)任務(wù),系統(tǒng)的整體吞吐量(單位時(shí)間內(nèi)完成的任務(wù)數(shù)量)也會(huì)降低 。就像一條高速公路上,車輛頻繁地變道、進(jìn)出服務(wù)區(qū),會(huì)導(dǎo)致道路擁堵,車輛行駛速度變慢,單位時(shí)間內(nèi)通過(guò)的車輛數(shù)量減少 。在一個(gè)多線程的服務(wù)器應(yīng)用中,如果線程上下文切換過(guò)于頻繁,每個(gè)線程處理請(qǐng)求的時(shí)間都會(huì)增加,服務(wù)器在單位時(shí)間內(nèi)能夠處理的請(qǐng)求數(shù)量就會(huì)減少,影響服務(wù)器的性能和響應(yīng)能力 。

四、如何監(jiān)控上下文切換

了解了 CPU 上下文切換的相關(guān)知識(shí)后,在實(shí)際的系統(tǒng)運(yùn)維和性能優(yōu)化工作中,我們還需要掌握如何監(jiān)控上下文切換,以便及時(shí)發(fā)現(xiàn)潛在的性能問(wèn)題。在 Linux 系統(tǒng)中,有一些實(shí)用的命令可以幫助我們實(shí)現(xiàn)這一目的。

4.1vmstat 命令

vmstat是一個(gè)常用的系統(tǒng)性能分析工具,它不僅能展示系統(tǒng)的內(nèi)存使用情況,還常被用于分析 CPU 上下文切換和中斷次數(shù) 。使用vmstat命令時(shí),一般會(huì)帶上兩個(gè)數(shù)字參數(shù),第一個(gè)參數(shù)表示采樣的時(shí)間間隔(單位是秒),第二個(gè)參數(shù)表示采樣的次數(shù) 。例如,執(zhí)行vmstat 5,表示每 5 秒輸出一次系統(tǒng)狀態(tài)信息 。其輸出結(jié)果中,與上下文切換相關(guān)的重要列有:

  • cs(context switch):表示每秒上下文切換的次數(shù) 。這個(gè)數(shù)值越高,說(shuō)明系統(tǒng)中任務(wù)之間的切換越頻繁 。
  • in(interrupt):表示每秒中斷的次數(shù) 。中斷次數(shù)的增加可能與硬件設(shè)備的活動(dòng)有關(guān),也可能影響上下文切換的頻率 。
  • r(Running or Runnable):就緒隊(duì)列的長(zhǎng)度,即正在運(yùn)行和等待 CPU 的進(jìn)程數(shù) 。如果這個(gè)值持續(xù)大于 CPU 核心數(shù),說(shuō)明可能存在 CPU 資源不足的情況,導(dǎo)致進(jìn)程在就緒隊(duì)列中等待,進(jìn)而引發(fā)更多的上下文切換 。
  • b(Blocked):處于不可中斷睡眠狀態(tài)的進(jìn)程數(shù) 。這些進(jìn)程通常是在等待 I/O 操作完成等關(guān)鍵資源,當(dāng)它們被喚醒時(shí),可能會(huì)導(dǎo)致上下文切換 。

假設(shè)我們執(zhí)行vmstat 5后,得到如下輸出:

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
0  0      0 6893400   2352 563768    0    0     2   425  153   32  1  3 96  0  0

從這個(gè)結(jié)果中,我們可以看到當(dāng)前系統(tǒng)每秒的上下文切換次數(shù)cs是 32 次,系統(tǒng)中斷次數(shù)in是 153 次,就緒隊(duì)列長(zhǎng)度r和不可中斷狀態(tài)進(jìn)程數(shù)b都是 0 。通過(guò)持續(xù)觀察這些指標(biāo),我們可以了解系統(tǒng)上下文切換的整體趨勢(shì)和狀態(tài) 。如果發(fā)現(xiàn)cs值突然大幅增加,就需要進(jìn)一步排查原因,可能是系統(tǒng)中運(yùn)行的進(jìn)程數(shù)量過(guò)多、進(jìn)程間競(jìng)爭(zhēng)資源激烈,或者存在某些頻繁觸發(fā)中斷的硬件設(shè)備等 。

4.2pidstat 命令

vmstat命令給出的是系統(tǒng)總體的上下文切換情況,如果我們想要查看每個(gè)進(jìn)程或線程的詳細(xì)上下文切換情況,就需要用到pidstat命令 。給pidstat加上-w選項(xiàng),便可以查看每個(gè)進(jìn)程上下文切換的情況 ;若再加上-t選項(xiàng),則可以查看進(jìn)程中線程的上下文切換情況 。例如,執(zhí)行pidstat -w 5,表示每隔 5 秒輸出一次每個(gè)進(jìn)程的上下文切換信息 。輸出結(jié)果中,重點(diǎn)關(guān)注的列有:

  • cswch/s:表示每秒自愿上下文切換(voluntary context switches)的次數(shù) 。當(dāng)進(jìn)程無(wú)法獲取所需資源(如 I/O、內(nèi)存等系統(tǒng)資源不足)時(shí),就會(huì)發(fā)生自愿上下文切換 。比如,一個(gè)進(jìn)程需要讀取磁盤文件,但磁盤 I/O 繁忙,該進(jìn)程就會(huì)主動(dòng)讓出 CPU,等待磁盤操作完成,從而導(dǎo)致自愿上下文切換 。
  • nvcswch/s:表示每秒非自愿上下文切換(non - voluntary context switches)的次數(shù) 。進(jìn)程由于時(shí)間片已到等原因,被系統(tǒng)強(qiáng)制調(diào)度,就會(huì)發(fā)生非自愿上下文切換 。例如,當(dāng)多個(gè)進(jìn)程都在爭(zhēng)搶 CPU 時(shí),每個(gè)進(jìn)程的時(shí)間片用完后,就會(huì)被系統(tǒng)強(qiáng)制切換,以保證其他進(jìn)程也有機(jī)會(huì)執(zhí)行 。

假設(shè)執(zhí)行pidstat -w 5后,得到如下部分結(jié)果:

15:04:39      UID       PID   cswch/s nvcswch/s  Command
15:04:44    0         1      0.20      0.00  systemd
15:04:44    0        11     27.94      0.00  rcu_sched
15:04:44    0       497     19.56      0.00  xfsaild/vda3

從這個(gè)結(jié)果中,我們可以看到不同進(jìn)程的自愿上下文切換次數(shù)cswch/s和非自愿上下文切換次數(shù)nvcswch/s 。通過(guò)分析這些數(shù)據(jù),我們能更有針對(duì)性地找出導(dǎo)致上下文切換頻繁的進(jìn)程,進(jìn)而對(duì)其進(jìn)行優(yōu)化 。如果某個(gè)進(jìn)程的cswch/s值很高,可能需要檢查該進(jìn)程的資源使用情況,看是否存在資源競(jìng)爭(zhēng)或 I/O 瓶頸等問(wèn)題;如果nvcswch/s值很高,可能意味著系統(tǒng)中 CPU 資源緊張,需要考慮優(yōu)化進(jìn)程調(diào)度策略或增加 CPU 資源 。

五、減少上下文切換的優(yōu)化策略

既然頻繁的上下文切換會(huì)對(duì)系統(tǒng)性能產(chǎn)生負(fù)面影響,那么我們?cè)撊绾螠p少上下文切換,優(yōu)化系統(tǒng)性能呢?下面為大家介紹幾種有效的優(yōu)化策略。

5.1合理設(shè)置進(jìn)程與線程數(shù)量

在系統(tǒng)中運(yùn)行的進(jìn)程和線程數(shù)量并非越多越好。過(guò)多的進(jìn)程或線程會(huì)導(dǎo)致它們競(jìng)爭(zhēng) CPU 資源,從而增加上下文切換的頻率 。因此,我們需要根據(jù)系統(tǒng)的實(shí)際情況,合理設(shè)置進(jìn)程和線程的數(shù)量 。對(duì)于計(jì)算密集型任務(wù),由于任務(wù)主要消耗 CPU 資源,線程數(shù)過(guò)多會(huì)導(dǎo)致頻繁的上下文切換,降低 CPU 利用率 。一般來(lái)說(shuō),線程數(shù)設(shè)置為 CPU 核心數(shù)加 1 較為合適 ,例如,對(duì)于一個(gè) 4 核心的 CPU,計(jì)算密集型任務(wù)的線程數(shù)可以設(shè)置為 5 。

這是因?yàn)楫?dāng)其中一個(gè)線程在執(zhí)行 I/O 等操作而阻塞時(shí),其他線程可以繼續(xù)使用 CPU,充分利用 CPU 資源,同時(shí)又不會(huì)因?yàn)榫€程過(guò)多而導(dǎo)致頻繁的上下文切換 。而對(duì)于 I/O 密集型任務(wù),由于任務(wù)大部分時(shí)間在等待 I/O 操作完成,CPU 利用率較低,此時(shí)可以適當(dāng)增加線程數(shù),以充分利用 CPU 空閑時(shí)間 。通常,線程數(shù)可以設(shè)置為 CPU 核心數(shù)的 2 倍甚至更多 。例如,對(duì)于 4 核心的 CPU,I/O 密集型任務(wù)的線程數(shù)可以設(shè)置為 8 - 10 。這樣,當(dāng)某個(gè)線程在等待 I/O 時(shí),其他線程可以及時(shí)被調(diào)度執(zhí)行,提高系統(tǒng)的整體效率 。

5.2優(yōu)化 I/O 操作

I/O 操作通常是比較耗時(shí)的,當(dāng)進(jìn)程或線程進(jìn)行 I/O 操作時(shí),往往會(huì)處于阻塞狀態(tài),導(dǎo)致 CPU 資源的閑置,進(jìn)而引發(fā)上下文切換 。為了減少因 I/O 等待導(dǎo)致的上下文切換,我們可以采用異步 I/O、非阻塞 I/O 等技術(shù) 。異步 I/O 允許進(jìn)程在發(fā)起 I/O 請(qǐng)求后,不必等待 I/O 操作完成,而是繼續(xù)執(zhí)行其他任務(wù) 。當(dāng) I/O 操作完成后,系統(tǒng)會(huì)通過(guò)回調(diào)函數(shù)或事件通知進(jìn)程 。這樣,在 I/O 操作進(jìn)行的過(guò)程中,CPU 可以被其他任務(wù)使用,避免了因 I/O 等待而造成的上下文切換 。

在 Linux 系統(tǒng)中,可以使用aio_read()、aio_write()等函數(shù)實(shí)現(xiàn)異步 I/O 。非阻塞 I/O 則是指進(jìn)程在進(jìn)行 I/O 操作時(shí),如果 I/O 設(shè)備尚未準(zhǔn)備好,不會(huì)阻塞進(jìn)程,而是立即返回一個(gè)錯(cuò)誤代碼,讓進(jìn)程可以繼續(xù)執(zhí)行其他操作 。進(jìn)程可以通過(guò)輪詢的方式,檢查 I/O操作是否完成 。這種方式也能減少 I/O 等待時(shí)間,降低上下文切換的頻率 。在 Java 中,NIO(New I/O)包提供了非阻塞I/O的支持,通過(guò)Selector和Channel等類,可以實(shí)現(xiàn)高效的非阻塞 I/O操作 。

5.3調(diào)整優(yōu)先級(jí)與親和性調(diào)度

合理分配進(jìn)程的優(yōu)先級(jí)可以減少上下文切換 。將重要的、對(duì)實(shí)時(shí)性要求高的進(jìn)程設(shè)置為較高的優(yōu)先級(jí),確保它們能夠優(yōu)先獲得 CPU 資源,減少被其他進(jìn)程搶占的可能性,從而降低上下文切換的次數(shù) 。在 Linux 系統(tǒng)中,可以使用nice命令或renice命令來(lái)調(diào)整進(jìn)程的優(yōu)先級(jí) 。nice命令用于在進(jìn)程啟動(dòng)時(shí)設(shè)置優(yōu)先級(jí),renice命令則可以在進(jìn)程運(yùn)行過(guò)程中改變其優(yōu)先級(jí) 。例如,nice -n -5 program表示將program進(jìn)程的優(yōu)先級(jí)設(shè)置為 - 5(優(yōu)先級(jí)范圍是 - 20 到 19,數(shù)值越小優(yōu)先級(jí)越高) 。

此外,設(shè)置處理器親和性也有助于減少上下文切換 。處理器親和性是指將進(jìn)程或線程綁定到特定的 CPU 核心上運(yùn)行 。這樣做可以避免進(jìn)程在不同 CPU 核心之間頻繁遷移,減少因跨 CPU 調(diào)度而導(dǎo)致的上下文切換 。在 Linux 系統(tǒng)中,可以使用taskset命令來(lái)設(shè)置進(jìn)程的 CPU 親和性 。比如,taskset -p 0x1 1234表示將進(jìn)程 ID 為 1234 的進(jìn)程綁定到 CPU 的第 0 個(gè)核心上運(yùn)行(0x1 表示二進(jìn)制的 0001,對(duì)應(yīng)第 0 個(gè)核心) 。通過(guò)合理設(shè)置處理器親和性,使得進(jìn)程在固定的 CPU 核心上運(yùn)行,該核心的緩存可以更好地被利用,減少緩存失效的情況,提高進(jìn)程的執(zhí)行效率,同時(shí)也減少了上下文切換帶來(lái)的開(kāi)銷 。

5.4減少鎖競(jìng)爭(zhēng)

在多線程環(huán)境中,鎖是常用的同步機(jī)制,但鎖競(jìng)爭(zhēng)會(huì)導(dǎo)致線程等待,進(jìn)而引發(fā)上下文切換 。我們可以通過(guò)優(yōu)化程序設(shè)計(jì)來(lái)減少鎖競(jìng)爭(zhēng) 。縮小鎖的使用范圍,只在必要的代碼塊上加鎖,而不是對(duì)整個(gè)方法或較大的代碼區(qū)域加鎖 。例如,在一個(gè)包含多個(gè)操作的方法中,如果只有部分操作涉及共享資源的訪問(wèn),那么只對(duì)這部分操作加鎖,而不是對(duì)整個(gè)方法加鎖 。這樣可以減少線程持有鎖的時(shí)間,降低鎖競(jìng)爭(zhēng)的可能性 。降低鎖的粒度,將大的鎖分解為多個(gè)小的鎖 。

以ConcurrentHashMap為例,它采用了分段鎖的機(jī)制,將整個(gè)哈希表分成多個(gè)段,每個(gè)段都有自己的鎖 。當(dāng)多個(gè)線程訪問(wèn)不同段的數(shù)據(jù)時(shí),不會(huì)發(fā)生鎖競(jìng)爭(zhēng),從而提高了并發(fā)性能 。還可以使用讀寫鎖來(lái)代替獨(dú)占鎖 。在讀取操作遠(yuǎn)多于寫入操作的場(chǎng)景中,讀寫鎖允許多個(gè)線程同時(shí)進(jìn)行讀取操作,只有在寫入操作時(shí)才需要獨(dú)占鎖,這樣可以大大提高并發(fā)性能 。

六、案例分析:高負(fù)載服務(wù)器的性能問(wèn)題

6.1場(chǎng)景描述

某服務(wù)器運(yùn)行多個(gè)Java應(yīng)用實(shí)例,出現(xiàn)響應(yīng)延遲飆升的現(xiàn)象。通過(guò)監(jiān)控發(fā)現(xiàn):

  • CPU使用率不高(約30%),但系統(tǒng)吞吐量下降。
  • vmstat顯示cs(context switches)指標(biāo)異常高(每秒超過(guò)10萬(wàn)次)。

6.2排查步驟

(1) 確認(rèn)上下文切換頻率

# 使用 vmstat 查看全局上下文切換情況
vmstat 1

輸出關(guān)鍵列:

  • cs:每秒上下文切換次數(shù)。
  • in:中斷次數(shù)。若cs顯著高于正常值(如從幾千飆升至幾十萬(wàn)),可能是頻繁調(diào)度導(dǎo)致。

(2) 定位具體進(jìn)程

# 使用 pidstat 查看各進(jìn)程的上下文切換情況
pidstat -w -u 1

# 輸出示例:
# PID    %usr %system   cswch/s nvcswch/s
# 12345   20     15      8000    50000
  • cswch/s:自愿上下文切換(如等待I/O)。
  • nvcswch/s:非自愿上下文切換(如時(shí)間片耗盡被強(qiáng)制調(diào)度)。

問(wèn)題發(fā)現(xiàn):某個(gè)Java進(jìn)程的nvcswch/s異常高,表明該進(jìn)程因CPU競(jìng)爭(zhēng)被頻繁搶占。

(3) 分析線程狀態(tài)

# top命令查看線程級(jí)別的CPU和狀態(tài)
top -H -p <PID>

# perf工具分析調(diào)度事件
perf sched record -p <PID> -- sleep 5
perf sched latency --sort max

可能發(fā)現(xiàn):

  • 大量線程處于RUNNABLE狀態(tài),競(jìng)爭(zhēng)有限的CPU資源。
  • SCHEDULER相關(guān)的延遲較高。

(4) JVM內(nèi)部診斷

如果是Java應(yīng)用,進(jìn)一步檢查:

jstack <PID> > thread_dump.txt

分析線程堆棧,常見(jiàn)問(wèn)題:

  • 鎖競(jìng)爭(zhēng):大量線程阻塞在同步鎖上。
  • 過(guò)度創(chuàng)建線程:線程池配置不合理。

6.3Root Cause &解決方案

  • 解決過(guò)多活躍線程:超出CPU核心數(shù),導(dǎo)致頻繁調(diào)度,調(diào)整線程池大小(如改為CPU核心數(shù) * (1 + wait_time/compute_time))。
  • 解決鎖競(jìng)爭(zhēng)激烈:優(yōu)化同步機(jī)制(如改用并發(fā)容器、減小鎖粒度)。
  • 解決進(jìn)程優(yōu)先級(jí)設(shè)置不當(dāng):通過(guò)nice/chrt調(diào)整優(yōu)先級(jí)。
  • 解決NUMA架構(gòu)影響:綁定進(jìn)程到特定NUMA節(jié)點(diǎn)(numactl --cpubind=node --membind=node)。

6.4關(guān)鍵工具總結(jié)

工具

作用

vmstat

查看全局上下文切換和中斷頻率

pidstat

定位高上下文切換的進(jìn)程

perf sched

分析調(diào)度延遲和熱點(diǎn)

jstack/top -H

檢查線程狀態(tài)和堆棧


責(zé)任編輯:武曉燕 來(lái)源: 深度Linux
相關(guān)推薦

2019-05-06 14:36:48

CPULinux寄存器

2020-09-28 08:44:17

Linux內(nèi)核

2022-04-24 15:37:26

LinuxCPU

2022-09-26 23:36:33

Linux系統(tǒng)CPU

2022-04-25 11:27:34

LinuxCPU

2020-07-24 10:00:00

JavaScript執(zhí)行上下文前端

2024-08-27 09:46:39

Go協(xié)程效率

2024-03-19 09:15:12

服務(wù)器CPUI/O

2019-03-14 08:00:00

JavaScript執(zhí)行棧前端

2021-05-25 11:10:36

GitLinux

2023-11-24 16:18:15

操作系統(tǒng)Linux

2022-09-05 08:02:10

上下文切換服務(wù)器

2024-11-06 12:59:42

多線程銷毀線程切換

2022-03-30 15:25:28

鏈接過(guò)程計(jì)算機(jī)系統(tǒng)程序

2021-07-26 07:47:36

Cpu上下文進(jìn)程

2012-07-18 11:39:18

ibmdw

2017-05-11 14:00:02

Flask請(qǐng)求上下文應(yīng)用上下文

2020-02-21 10:09:06

調(diào)度進(jìn)程線程

2023-10-27 07:47:37

計(jì)算機(jī)內(nèi)存模型

2020-07-02 08:17:12

存儲(chǔ)IO
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 懂色中文一区二区在线播放 | www视频在线观看 | 9久久婷婷国产综合精品性色 | 精品少妇一区二区三区日产乱码 | 日本欧美在线观看视频 | 日韩精品成人免费观看视频 | 国产精品一区二区三区四区五区 | 日日日视频| 亚洲入口 | 欧美精品一区二区三区蜜桃视频 | 一区二区三区四区在线 | 热99视频 | 日韩欧美三区 | 午夜欧美日韩 | av中文字幕网 | 黄色在线免费观看 | 男女羞羞视频在线 | 91影院在线观看 | 国产不卡在线播放 | 午夜精品久久久 | 91久色| 欧美黄视频 | 日韩欧美国产精品 | 亚洲欧美精品在线观看 | 成人免费视频网站在线看 | 国产1区2区3区 | 天天射天天干 | 国产婷婷精品av在线 | 日日夜夜免费精品视频 | 欧美日韩视频 | 在线成人免费观看 | www.99re| 日韩av一二三区 | 久久精品| 亚洲综合视频 | 日韩免费视频一区二区 | 日韩欧美在线视频 | 午夜精品在线 | 久久一级免费视频 | 欧美性生活网 | 亚洲国产片 |