進(jìn)程在競(jìng)爭(zhēng) CPU 的時(shí)候并沒(méi)有真正運(yùn)行,系統(tǒng)的負(fù)載也會(huì)升高。
創(chuàng)新互聯(lián)主營(yíng)禪城網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,成都app軟件開(kāi)發(fā)公司,禪城h5成都小程序開(kāi)發(fā)搭建,禪城網(wǎng)站營(yíng)銷(xiāo)推廣歡迎禪城等地區(qū)企業(yè)咨詢(xún)Linux 是一個(gè)多任務(wù)操作系統(tǒng),它支持遠(yuǎn)大于 CPU 數(shù)量的任務(wù)同時(shí)運(yùn)行,在每個(gè)任務(wù)運(yùn)行前,CPU 都需要知道任務(wù)從哪里加載、又從哪里開(kāi)始運(yùn)行,也就是說(shuō),需要系統(tǒng)事先幫它設(shè)置好 CPU 寄存器和程序計(jì)數(shù)器(Program Counter,PC)。
CPU 寄存器,是 CPU 內(nèi)置的容量小、但速度極快的內(nèi)存。而程序計(jì)數(shù)器,則是用來(lái)存儲(chǔ) CPU 正在執(zhí)行的指令位置、或者即將執(zhí)行的下一條指令位置。它們都是 CPU 在運(yùn)行任何任務(wù)前,必須的依賴(lài)環(huán)境,因此也被叫做 CPU 上下文。
Linux 按照特權(quán)等級(jí),把進(jìn)程的運(yùn)行空間分為內(nèi)核空間和用戶(hù)空間。
內(nèi)核空間(Ring 0)具有最高權(quán)限,可以直接訪(fǎng)問(wèn)所有資源;
用戶(hù)空間(Ring 3)只能訪(fǎng)問(wèn)受限資源,不能直接訪(fǎng)問(wèn)內(nèi)存等硬件設(shè)備,必須通過(guò)系統(tǒng)調(diào)用陷入到內(nèi)核中,才能訪(fǎng)問(wèn)這些特權(quán)資源。
從用戶(hù)態(tài)到內(nèi)核態(tài)的轉(zhuǎn)變,需要通過(guò)系統(tǒng)調(diào)用來(lái)完成。
比如,當(dāng)我們查看文件內(nèi)容時(shí),就需要多次系統(tǒng)調(diào)用來(lái)完成:首先調(diào)用 open() 打開(kāi)文件,然后調(diào)用 read() 讀取文件內(nèi)容,并調(diào)用 write() 將內(nèi)容寫(xiě)到標(biāo)準(zhǔn)輸出,最后再調(diào)用 close() 關(guān)閉文件。
系統(tǒng)調(diào)用的過(guò)程會(huì)涉及到CPU 上下文的切換,CPU 寄存器里原來(lái)用戶(hù)態(tài)的指令位置,需要先保存起來(lái)。接著,為了執(zhí)行內(nèi)核態(tài)代碼,CPU 寄存器需要更新為內(nèi)核態(tài)指令的新位置。最后才是跳轉(zhuǎn)到內(nèi)核態(tài)運(yùn)行內(nèi)核任務(wù),而系統(tǒng)調(diào)用結(jié)束后,CPU 寄存器需要恢復(fù)原來(lái)保存的用戶(hù)態(tài),然后再切換到用戶(hù)空間,繼續(xù)運(yùn)行進(jìn)程。所以,一次系統(tǒng)調(diào)用的過(guò)程,其實(shí)是發(fā)生了兩次 CPU 上下文切換。
進(jìn)程是由內(nèi)核來(lái)管理和調(diào)度的,進(jìn)程的切換只能發(fā)生在內(nèi)核態(tài)。所以,進(jìn)程的上下文不僅包括了虛擬內(nèi)存、棧、全局變量等用戶(hù)空間的資源,還包括了內(nèi)核堆棧、寄存器等內(nèi)核空間的狀態(tài)。
進(jìn)程的上下文切換就比系統(tǒng)調(diào)用時(shí)多了一步:在保存當(dāng)前進(jìn)程的內(nèi)核狀態(tài)和 CPU 寄存器之前,需要先把該進(jìn)程的虛擬內(nèi)存、棧等保存下來(lái);而加載了下一進(jìn)程的內(nèi)核態(tài)后,還需要刷新進(jìn)程的虛擬內(nèi)存和用戶(hù)棧。
線(xiàn)程上下文切換上下文切換都需要幾十納秒到數(shù)微秒的 CPU 時(shí)間。
線(xiàn)程與進(jìn)程大的區(qū)別在于,線(xiàn)程是調(diào)度的基本單位,而進(jìn)程則是資源擁有的基本單位。內(nèi)核中的任務(wù)調(diào)度,實(shí)際上的調(diào)度對(duì)象是線(xiàn)程。
當(dāng)進(jìn)程只有一個(gè)線(xiàn)程時(shí),可以認(rèn)為進(jìn)程就等于線(xiàn)程。
當(dāng)進(jìn)程擁有多個(gè)線(xiàn)程時(shí),這些線(xiàn)程會(huì)共享相同的虛擬內(nèi)存和全局變量等資源。這些資源在上下文切換時(shí)是不需要修改的。
另外,線(xiàn)程也有自己的私有數(shù)據(jù),比如棧和寄存器等,這些在上下文切換時(shí)也是需要保存的。
線(xiàn)程的上下文切換其實(shí)就可以分為兩種情況:
為了快速響應(yīng)硬件的事件,中斷處理會(huì)打斷進(jìn)程的正常調(diào)度和執(zhí)行,轉(zhuǎn)而調(diào)用中斷處理程序,響應(yīng)設(shè)備事件。而在打斷其他進(jìn)程時(shí),就需要將進(jìn)程當(dāng)前的狀態(tài)保存下來(lái),這樣在中斷結(jié)束后,進(jìn)程仍然可以從原來(lái)的狀態(tài)恢復(fù)運(yùn)行。
中斷上下文切換并不涉及到進(jìn)程的用戶(hù)態(tài),所以,即便中斷過(guò)程打斷了一個(gè)正處在用戶(hù)態(tài)的進(jìn)程,也不需要保存和恢復(fù)這個(gè)進(jìn)程的虛擬內(nèi)存、全局變量等用戶(hù)態(tài)資源。中斷上下文,其實(shí)只包括內(nèi)核態(tài)中斷服務(wù)程序執(zhí)行所必需的狀態(tài),包括 CPU 寄存器、內(nèi)核堆棧、硬件中斷參數(shù)等。
進(jìn)程調(diào)度觸發(fā)情況中斷上下文切換也需要消耗 CPU,切換次數(shù)過(guò)多也會(huì)耗費(fèi)大量的 CPU,甚至嚴(yán)重降低系統(tǒng)的整體性能。
vmstat 是一個(gè)常用的系統(tǒng)性能分析工具,主要用來(lái)分析系統(tǒng)的內(nèi)存使用情況,也常用來(lái)分析 CPU 上下文切換和中斷的次數(shù)。
# 每隔 5 秒輸出 1 組數(shù)據(jù)
$ 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 7005360 91564 818900 0 0 0 0 25 33 0 0 100 0 0
pidstatcs(context switch)是每秒上下文切換的次數(shù)。
in(interrupt)則是每秒中斷的次數(shù)。
r(Running or Runnable)是就緒隊(duì)列的長(zhǎng)度,也就是正在運(yùn)行和等待 CPU 的進(jìn)程數(shù)。
b(Blocked)則是處于不可中斷睡眠狀態(tài)的進(jìn)程數(shù)。
sysstat 包含了常用的 Linux 性能工具,用來(lái)監(jiān)控和分析系統(tǒng)的性能。
pidstat是其中一個(gè)常用的進(jìn)程性能分析工具,用來(lái)實(shí)時(shí)查看進(jìn)程的 CPU、內(nèi)存、I/O 以及上下文切換等性能指標(biāo)。
vmstat 只給出了系統(tǒng)總體的上下文切換情況,要想查看每個(gè)進(jìn)程的詳細(xì)情況,就需要使用我們上面提到過(guò)的 pidstat 了。給它加上 -w 選項(xiàng),你就可以查看每個(gè)進(jìn)程上下文切換的情況了。
# 每隔 5 秒輸出 1 組數(shù)據(jù)
$ pidstat -w 5
Linux 4.15.0 (ubuntu) 09/23/18 _x86_64_ (2 CPU)
08:18:26 UID PID cswch/s nvcswch/s Command
08:18:31 0 1 0.20 0.00 systemd
08:18:31 0 8 5.40 0.00 rcu_sched
# 每隔 1 秒輸出一組數(shù)據(jù)(需要 Ctrl+C 才結(jié)束)
# -wt 參數(shù)表示輸出線(xiàn)程的上下文切換指標(biāo)
$ pidstat -wt 1
08:14:05 UID TGID TID cswch/s nvcswch/s Command
...
08:14:05 0 10551 - 6.00 0.00 sysbench
08:14:05 0 - 10551 6.00 0.00 |__sysbench
08:14:05 0 - 10552 18911.00 103740.00 |__sysbench
08:14:05 0 - 10553 18915.00 100955.00 |__sysbench
08:14:05 0 - 10554 18827.00 103954.00 |__sysbench
判斷中斷上下文切換的原因cswch 自愿上下文切換,是指進(jìn)程無(wú)法獲取所需資源,導(dǎo)致的上下文切換。比如說(shuō), I/O、內(nèi)存等系統(tǒng)資源不足時(shí),就會(huì)發(fā)生自愿上下文切換。
nvcswch 非自愿上下文切換,則是指進(jìn)程由于時(shí)間片已到等原因,被系統(tǒng)強(qiáng)制調(diào)度,進(jìn)而發(fā)生的上下文切換。比如說(shuō),大量進(jìn)程都在爭(zhēng)搶 CPU 時(shí),就容易發(fā)生非自愿上下文切換。
/proc 實(shí)際上是 Linux 的一個(gè)虛擬文件系統(tǒng),用于內(nèi)核空間與用戶(hù)空間之間的通信。/proc/interrupts 就是這種通信機(jī)制的一部分,提供了一個(gè)只讀的中斷使用情況。
# -d 參數(shù)表示高亮顯示變化的區(qū)域
$ watch -d cat /proc/interrupts
CPU0 CPU1
...
RES: 2450431 5279697 Rescheduling interrupts
...
變化速度最快的是重調(diào)度中斷(RES),這個(gè)中斷類(lèi)型表示,喚醒空閑狀態(tài)的 CPU 來(lái)調(diào)度新的任務(wù)運(yùn)行。這是多處理器系統(tǒng)(SMP)中,調(diào)度器用來(lái)分散任務(wù)到不同 CPU 的機(jī)制,通常也被稱(chēng)為處理器間中斷(Inter-Processor Interrupts,IPI)。
但當(dāng)上下文切換次數(shù)超過(guò)一萬(wàn)次,或者切換次數(shù)出現(xiàn)數(shù)量級(jí)的增長(zhǎng)時(shí),就很可能已經(jīng)出現(xiàn)了性能問(wèn)題。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧