人空閑時(shí)會(huì)發(fā)呆會(huì)無(wú)聊,計(jì)算機(jī)呢?
假設(shè)你正在用計(jì)算機(jī)瀏覽網(wǎng)頁(yè),當(dāng)網(wǎng)頁(yè)加載完成后你開(kāi)始閱讀,此時(shí)你沒(méi)有移動(dòng)鼠標(biāo),沒(méi)有敲擊鍵盤(pán),也沒(méi)有網(wǎng)絡(luò)通信,那么你的計(jì)算機(jī)此時(shí)在干嘛?
你的計(jì)算機(jī) CPU 使用率是多少?
如果此時(shí)你正在計(jì)算機(jī)旁,并且安裝有 Windows 或者 Linux ,你可以立刻看到自己的計(jì)算機(jī) CPU 使用率是多少。 這是博主的一臺(tái)安裝有 Win10 的電腦:
可以看到大部分情況下 CPU 利用率很低,也就在 8% 左右,而且開(kāi)啟了 283 個(gè)進(jìn)程,這么多進(jìn)程基本上無(wú)所事事,都在等待某個(gè)特定事件來(lái)喚醒自己,就好比你寫(xiě)了一個(gè)打印用戶(hù)輸入的程序,如果用戶(hù)一直不按鍵盤(pán),那么你的進(jìn)程就處于這種狀態(tài)。 那么有的同學(xué)可能會(huì)問(wèn),剩下的 CPU 時(shí)間都去哪里了?
這個(gè)問(wèn)題也很簡(jiǎn)單,還是以 Win10 為例,打開(kāi)任務(wù)管理器,找到 “詳細(xì)信息” 這一欄,你會(huì)發(fā)現(xiàn)有一個(gè) “系統(tǒng)空閑進(jìn)程”,其 CPU 使用率達(dá)到了 99%,正是這個(gè)進(jìn)程消耗了幾乎所有的 CPU 時(shí)間。
那么為什么存在這樣一個(gè)進(jìn)程呢?以及這個(gè)進(jìn)程什么時(shí)候開(kāi)始運(yùn)行呢? 這就要從操作系統(tǒng)說(shuō)起了。
程序、進(jìn)程與操作系統(tǒng)
當(dāng)你用最喜歡的代碼編輯器編寫(xiě)代碼時(shí),這時(shí)的代碼不過(guò)就是磁盤(pán)上的普通文件,此時(shí)的程序和操作系統(tǒng)沒(méi)有半毛錢(qián)關(guān)系,操作系統(tǒng)也不認(rèn)知這種文本文件。
程序員寫(xiě)完代碼后開(kāi)始編譯,這時(shí)編譯器將普通的文本文件翻譯成二進(jìn)制可執(zhí)行文件,此時(shí)的程序依然是保存在磁盤(pán)上的文件,和普通沒(méi)有本質(zhì)區(qū)別。
但此時(shí)不一樣的是,該文件是可執(zhí)行文件,也就是說(shuō)操作系統(tǒng)開(kāi)始 “懂得” 這種文件,所謂 “懂得” 是指操作系統(tǒng)可以識(shí)別、解析、加載,因此必定有某種類(lèi)似協(xié)議的規(guī)范,這樣編譯器按照這種協(xié)議生成可執(zhí)行文件,操作系統(tǒng)就能加載了。 在 Linux 下可執(zhí)行文件格式為 ELF ,在 Windows 下是 EXE 。
此時(shí)雖然操作系統(tǒng)可以識(shí)別可執(zhí)行程序,但如果你不去雙擊一下(或者在Linux下運(yùn)行相應(yīng)命令)的依然和操作系統(tǒng)沒(méi)有半毛錢(qián)關(guān)系。
但是當(dāng)你運(yùn)行可執(zhí)行程序時(shí)魔法就出現(xiàn)了。 此時(shí)操作系統(tǒng)開(kāi)始將可執(zhí)行文件加載到內(nèi)存,解析出代碼段、數(shù)據(jù)段等,并為這個(gè)程序創(chuàng)建運(yùn)行時(shí)需要的堆區(qū)棧區(qū)等內(nèi)存區(qū)域,此時(shí)這個(gè)程序在內(nèi)存中就是這樣了:
最后,根據(jù)可執(zhí)行文件的內(nèi)容,操作系統(tǒng)知道該程序應(yīng)該執(zhí)行的第一條機(jī)器指令是什么,并將其告訴 CPU ,CPU 從該程序的第一條指令開(kāi)始執(zhí)行,程序就這樣運(yùn)行起來(lái)了。
一個(gè)在內(nèi)存中運(yùn)行起來(lái)的程序顯然和保存在磁盤(pán)上的二進(jìn)制文件是不一樣的,總的有個(gè)名字吧,根據(jù)“弄不懂原則”,這個(gè)名字就叫進(jìn)程,英文名叫做Process。
我們把一個(gè)運(yùn)行起來(lái)的程序叫做進(jìn)程,這就是進(jìn)程的由來(lái)。
此時(shí)操作系統(tǒng)開(kāi)始掌管進(jìn)程,現(xiàn)在進(jìn)程已經(jīng)有了,那么操作系統(tǒng)是怎么管理進(jìn)程的呢? 實(shí)際上在很多操作系統(tǒng)實(shí)現(xiàn)中都用隊(duì)列來(lái)管理進(jìn)程。
那么很顯然,如果隊(duì)列已經(jīng)為空,那么說(shuō)明此時(shí)操作系統(tǒng)內(nèi)部沒(méi)有進(jìn)程需要運(yùn)行,這是 CPU 就空閑下來(lái)了,此時(shí),我們需要做點(diǎn)什么,就像這樣:
if (queue.empty()) { do_someting(); }這些編寫(xiě)內(nèi)核代碼雖然簡(jiǎn)單,但內(nèi)核中到處充斥著 if 這種異常處理的語(yǔ)句,這會(huì)讓代碼看起來(lái)一團(tuán)糟,因此更好的設(shè)計(jì)是沒(méi)有異常,那么怎樣才能沒(méi)有異常呢?
很簡(jiǎn)單,那就是讓隊(duì)列永遠(yuǎn)不會(huì)空,這樣調(diào)度器永遠(yuǎn)能從隊(duì)列中找到一個(gè)可供運(yùn)行的進(jìn)程。
而這也是為什么鏈表中通常會(huì)有哨兵節(jié)點(diǎn)的原因,就是為了避免各種判空,這樣既容易出錯(cuò)也會(huì)讓代碼一團(tuán)糟。

就這樣,內(nèi)核設(shè)計(jì)者創(chuàng)建了一個(gè)叫做空閑任務(wù)的進(jìn)程,這個(gè)進(jìn)程就是Windows 下的我們最開(kāi)始看到的“系統(tǒng)空閑進(jìn)程”,在 Linux 下就是第 0號(hào)進(jìn)程。
當(dāng)其它進(jìn)程都處于不可運(yùn)行狀態(tài)時(shí),調(diào)度器就從隊(duì)列中取出空閑進(jìn)程運(yùn)行,顯然,空閑進(jìn)程永遠(yuǎn)處于就緒狀態(tài),且優(yōu)先級(jí)最低。
既然我們已經(jīng)知道了,當(dāng)系統(tǒng)無(wú)所事事后開(kāi)始運(yùn)行空閑進(jìn)程,那么這個(gè)空閑進(jìn)程到底在干嘛呢? 這就需要硬件來(lái)幫忙了。
一切都要?dú)w結(jié)到硬件
在計(jì)算機(jī)系統(tǒng)中,一切最終都要靠 CPU 來(lái)驅(qū)動(dòng),CPU 才是那個(gè)真正干活的。 原來(lái),CPU 設(shè)計(jì)者早就考慮到系統(tǒng)會(huì)存在空閑的可能,因此設(shè)計(jì)了一條機(jī)器指令,這個(gè)機(jī)器指令就是 halt 指令,停止的意思。
這條指令會(huì)讓部分CPU進(jìn)入休眠狀態(tài),從而極大減少對(duì)電力的消耗,通常這條指令也被放到循環(huán)中執(zhí)行,原因也很簡(jiǎn)單,就是要維持這種休眠狀態(tài)。
值得注意的是,halt 指令是特權(quán)指令,也就是說(shuō)只有在內(nèi)核態(tài)下 CPU 才可以執(zhí)行這條指令,程序員寫(xiě)的應(yīng)用都運(yùn)行在用戶(hù)態(tài),因此你沒(méi)有辦法在用戶(hù)態(tài)讓 CPU 去執(zhí)行這條指令。
軟件硬件結(jié)合
現(xiàn)在我們有了 halt 機(jī)器指令,同時(shí)有一個(gè)循環(huán)來(lái)不停的執(zhí)行 halt 指令,這樣空閑任務(wù)進(jìn)程的實(shí)際上就已經(jīng)實(shí)現(xiàn)了,其本質(zhì)上就是這個(gè)不斷執(zhí)行 halt 指令的循環(huán),大功告成。
這樣,當(dāng)調(diào)度器在沒(méi)有其它進(jìn)程可供調(diào)度時(shí)就開(kāi)始運(yùn)行空間進(jìn)程,也就是在循環(huán)中不斷的執(zhí)行 halt 指令,此時(shí) CPU 開(kāi)始進(jìn)入低功耗狀態(tài)。
在 Linux 內(nèi)核中,這段代碼是這樣寫(xiě)的:
while (1) { while(!need_resched()) { cpuidle_idle_call(); } }其中 cpuidle_idle_call函數(shù)最終會(huì)執(zhí)行 halt 指令,注意,這里刪掉了很多細(xì)節(jié),只保留最核心代碼,實(shí)際上 Linux 內(nèi)核在實(shí)現(xiàn)空閑進(jìn)程時(shí)還要考慮很多很多,不同類(lèi)型的 CPU 可能會(huì)有深睡眠淺睡眠之類(lèi),操作系統(tǒng)必須要預(yù)測(cè)出系統(tǒng)可能的空閑時(shí)長(zhǎng)并以此判斷要進(jìn)入哪種休眠等等,但這并不是我們關(guān)注的重點(diǎn)。
總的來(lái)說(shuō),這就是計(jì)算機(jī)系統(tǒng)空閑時(shí) CPU 在干嘛,就是在執(zhí)行這一段代碼,本質(zhì)上就是 CPU 在執(zhí)行 halt 指令。
實(shí)際上,對(duì)于個(gè)人計(jì)算機(jī)來(lái)說(shuō),halt 可能是 CPU 執(zhí)行最多的一條指令,全世界的 CPU 大部分時(shí)間都用在這條指令上了,是不是很奇怪。
審核編輯:劉清
-
cpu
+關(guān)注
關(guān)注
68文章
11080瀏覽量
217132 -
Linux
+關(guān)注
關(guān)注
87文章
11511瀏覽量
213852 -
計(jì)算機(jī)
+關(guān)注
關(guān)注
19文章
7663瀏覽量
90828 -
LINUX內(nèi)核
+關(guān)注
關(guān)注
1文章
317瀏覽量
22411
原文標(biāo)題:CPU 空閑時(shí)在干嘛?
文章出處:【微信號(hào):strongerHuang,微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
一種基于FreeRTOS的CPU使用率測(cè)算方法及原理介紹
請(qǐng)問(wèn)CPU使用率是怎么計(jì)算的?和節(jié)拍計(jì)數(shù)是什么關(guān)系?
UCOSIII統(tǒng)計(jì)任務(wù)如何計(jì)算CPU使用率
高CPU使用率問(wèn)題求解
cpu使用率忽高忽低問(wèn)題原因有哪些
cpu使用率多少算正常_cpu使用率100怎么辦
為什么明明沒(méi)開(kāi)多少軟件,計(jì)算的CPU使用率卻莫名的高

CPU使用率達(dá)到100%會(huì)怎樣
CPU使用率是什么意思
使用Bolt監(jiān)控CPU使用率

什么是CPU使用率?如何測(cè)量CPU使用率?
如何在Linux系統(tǒng)中檢查CPU使用率

評(píng)論