<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          CPU 空閑時在干嘛?

          共 3611字,需瀏覽 8分鐘

           ·

          2021-03-17 02:17

          人空閑時會發(fā)呆會無聊,計算機(jī)呢?

          假設(shè)你正在用計算機(jī)瀏覽網(wǎng)頁,當(dāng)網(wǎng)頁加載完成后你開始閱讀,此時你沒有移動鼠標(biāo),沒有敲擊鍵盤,也沒有網(wǎng)絡(luò)通信,那么你的計算機(jī)此時在干嘛?

          有的同學(xué)可能會覺得這個問題很簡單,但實際上,這個問題涉及從硬件到軟件、從 CPU 到操作系統(tǒng)等一系列環(huán)節(jié),理解了這個問題你就能明白操作系統(tǒng)是如何工作的了。


          你的計算機(jī) CPU 使用率是多少?

          如果此時你正在計算機(jī)旁,并且安裝有 Windows 或者 Linux ,你可以立刻看到自己的計算機(jī) CPU 使用率是多少。
          這是博主的一臺安裝有 Win10 的筆記本:
          可以看到大部分情況下 CPU 利用率很低,也就在 8% 左右,而且開啟了 283 個進(jìn)程,這么多進(jìn)程基本上無所事事,都在等待某個特定事件來喚醒自己,就好比你寫了一個打印用戶輸入的程序,如果用戶一直不按鍵盤,那么你的進(jìn)程就處于這種狀態(tài)。
          有的同學(xué)可能會想也就你的比較空閑吧,實際上大部分個人計算機(jī) CPU 使用率都差不多這樣(排除掉看電影、玩游戲等場景),如果你的使用率總是很高,風(fēng)扇一直在嗡嗡的轉(zhuǎn),那么不是軟件 bug 就有可能是病毒。。。
          那么有的同學(xué)可能會問,剩下的 CPU 時間都去哪里了?

          剩下的 CPU 時間去哪里了?
          這個問題也很簡單,還是以 Win10 為例,打開任務(wù)管理器,找到 “詳細(xì)信息” 這一欄,你會發(fā)現(xiàn)有一個 “系統(tǒng)空閑進(jìn)程”,其 CPU 使用率達(dá)到了 99%,正是這個進(jìn)程消耗了幾乎所有的 CPU 時間。
          那么為什么存在這樣一個進(jìn)程呢?以及這個進(jìn)程什么時候開始運行呢?
          這就要從操作系統(tǒng)說起了。

          程序、進(jìn)程與操作系統(tǒng)
          當(dāng)你用最喜歡的代碼編輯器編寫代碼時,這時的代碼不過就是磁盤上的普通文件,此時的程序和操作系統(tǒng)沒有半毛錢關(guān)系,操作系統(tǒng)也不認(rèn)知這種文本文件。
          程序員寫完代碼后開始編譯,這時編譯器將普通的文本文件翻譯成二進(jìn)制可執(zhí)行文件,此時的程序依然是保存在磁盤上的文件,和普通沒有本質(zhì)區(qū)別。
          但此時不一樣的是,該文件是可執(zhí)行文件,也就是說操作系統(tǒng)開始 “懂得” 這種文件,所謂 “懂得” 是指操作系統(tǒng)可以識別、解析、加載,因此必定有某種類似協(xié)議的規(guī)范,這樣編譯器按照這種協(xié)議生成可執(zhí)行文件,操作系統(tǒng)就能加載了。
          在 Linux 下可執(zhí)行文件格式為 ELF ,在 Windows 下是 EXE 。
          此時雖然操作系統(tǒng)可以識別可執(zhí)行程序,但如果你不去雙擊一下(或者在Linux下運行相應(yīng)命令)的依然和操作系統(tǒng)沒有半毛錢關(guān)系。
          但是當(dāng)你運行可執(zhí)行程序時魔法就出現(xiàn)了。
          此時操作系統(tǒng)開始將可執(zhí)行文件加載到內(nèi)存,解析出代碼段、數(shù)據(jù)段等,并為這個程序創(chuàng)建運行時需要的堆區(qū)棧區(qū)等內(nèi)存區(qū)域,此時這個程序在內(nèi)存中就是這樣了:
          最后,根據(jù)可執(zhí)行文件的內(nèi)容,操作系統(tǒng)知道該程序應(yīng)該執(zhí)行的第一條機(jī)器指令是什么,并將其告訴 CPU ,CPU 從該程序的第一條指令開始執(zhí)行,程序就這樣運行起來了。
          一個在內(nèi)存中運行起來的程序顯然和保存在磁盤上的二進(jìn)制文件是不一樣的,總的有個名字吧,根據(jù)“弄不懂原則”,這個名字就叫進(jìn)程,英文名叫做Process。
          我們把一個運行起來的程序叫做進(jìn)程,這就是進(jìn)程的由來。
          此時操作系統(tǒng)開始掌管進(jìn)程,現(xiàn)在進(jìn)程已經(jīng)有了,那么操作系統(tǒng)是怎么管理進(jìn)程的呢?

          調(diào)度器與進(jìn)程管理
          銀行想必大家都去過,實際上如果你仔細(xì)觀察的話銀行的辦事大廳就能體現(xiàn)出操作系統(tǒng)最核心的進(jìn)程管理與調(diào)度。
          首先大家去銀行都要排隊,類似的,進(jìn)程在操作系統(tǒng)中也是通過隊列來管理的。
          同時銀行還按照客戶的重要程度劃分了優(yōu)先級,大部分都是普通客戶;但當(dāng)你在這家銀行存上幾個億時就能升級為 VIP 客戶,優(yōu)先級最高,每次去銀行都不用排隊,優(yōu)先辦理你的業(yè)務(wù)。
          類似的,操作系統(tǒng)也會為進(jìn)程劃分優(yōu)先級,操作系統(tǒng)會根據(jù)進(jìn)程優(yōu)先級將其放到相應(yīng)的隊列中供調(diào)度器調(diào)度。
          這就是操作系統(tǒng)需要實現(xiàn)的最核心功能。
          現(xiàn)在準(zhǔn)備工作已經(jīng)就緒。
          接下來的問題就是操作系統(tǒng)如何確定是否還有進(jìn)程需要運行。

          隊列判空:一個更好的設(shè)計
          從上一節(jié)我們知道,實際上操作系統(tǒng)是用隊列來管理進(jìn)程的,那么很顯然,如果隊列已經(jīng)為空,那么說明此時操作系統(tǒng)內(nèi)部沒有進(jìn)程需要運行,這是 CPU 就空閑下來了,此時,我們需要做點什么,就像這樣:
          if (queue.empty()) { do_someting();}
          這些編寫內(nèi)核代碼雖然簡單,但內(nèi)核中到處充斥著 if 這種異常處理的語句,這會讓代碼看起來一團(tuán)糟,因此更好的設(shè)計是沒有異常,那么怎樣才能沒有異常呢?
          很簡單,那就是讓隊列永遠(yuǎn)不會空,這樣調(diào)度器永遠(yuǎn)能從隊列中找到一個可供運行的進(jìn)程。
          而這也是為什么鏈表中通常會有哨兵節(jié)點的原因,就是為了避免各種判空,這樣既容易出錯也會讓代碼一團(tuán)糟。
          就這樣,內(nèi)核設(shè)計者創(chuàng)建了一個叫做空閑任務(wù)的進(jìn)程,這個進(jìn)程就是Windows 下的我們最開始看到的“系統(tǒng)空閑進(jìn)程”,在 Linux 下就是第 0號進(jìn)程。
          當(dāng)其它進(jìn)程都處于不可運行狀態(tài)時,調(diào)度器就從隊列中取出空閑進(jìn)程運行,顯然,空閑進(jìn)程永遠(yuǎn)處于就緒狀態(tài),且優(yōu)先級最低。
          既然我們已經(jīng)知道了,當(dāng)系統(tǒng)無所事事后開始運行空閑進(jìn)程,那么這個空閑進(jìn)程到底在干嘛呢?
          這就需要硬件來幫忙了。

          一切都要歸結(jié)到硬件
          在計算機(jī)系統(tǒng)中,一切最終都要靠 CPU 來驅(qū)動,CPU 才是那個真正干活的。
          原來,CPU 設(shè)計者早就考慮到系統(tǒng)會存在空閑的可能,因此設(shè)計了一條機(jī)器指令,這個機(jī)器指令就是 halt 指令,停止的意思。
          這條指令會讓部分CPU進(jìn)入休眠狀態(tài),從而極大減少對電力的消耗,通常這條指令也被放到循環(huán)中執(zhí)行,原因也很簡單,就是要維持這種休眠狀態(tài)。
          值得注意的是,halt 指令是特權(quán)指令,也就是說只有在內(nèi)核態(tài)下 CPU 才可以執(zhí)行這條指令,程序員寫的應(yīng)用都運行在用戶態(tài),因此你沒有辦法在用戶態(tài)讓 CPU 去執(zhí)行這條指令。
          此外,不要把進(jìn)程掛起和 halt 指令混淆,當(dāng)我們調(diào)用 sleep 之類函數(shù)時,暫停運行的只是進(jìn)程,此時如果還有其它進(jìn)程可以運行那么 CPU 是不會空閑下來的,當(dāng) CPU 開始執(zhí)行halt指令時就意味著系統(tǒng)中所有進(jìn)程都已經(jīng)暫停運行。

          軟件硬件結(jié)合
          現(xiàn)在我們有了 halt 機(jī)器指令,同時有一個循環(huán)來不停的執(zhí)行 halt 指令,這樣空閑任務(wù)進(jìn)程的實際上就已經(jīng)實現(xiàn)了,其本質(zhì)上就是這個不斷執(zhí)行 halt 指令的循環(huán),大功告成。
          這樣,當(dāng)調(diào)度器在沒有其它進(jìn)程可供調(diào)度時就開始運行空間進(jìn)程,也就是在循環(huán)中不斷的執(zhí)行 halt 指令,此時 CPU 開始進(jìn)入低功耗狀態(tài)。
          在 Linux 內(nèi)核中,這段代碼是這樣寫的:
          while (1) { while(!need_resched()) { cpuidle_idle_call(); }}
          其中 cpuidle_idle_call函數(shù)最終會執(zhí)行 halt 指令,注意,這里刪掉了很多細(xì)節(jié),只保留最核心代碼,實際上 Linux 內(nèi)核在實現(xiàn)空閑進(jìn)程時還要考慮很多很多,不同類型的 CPU 可能會有深睡眠淺睡眠之類,操作系統(tǒng)必須要預(yù)測出系統(tǒng)可能的空閑時長并以此判斷要進(jìn)入哪種休眠等等,但這并不是我們關(guān)注的重點。
          總的來說,這就是計算機(jī)系統(tǒng)空閑時 CPU 在干嘛,就是在執(zhí)行這一段代碼,本質(zhì)上就是 CPU 在執(zhí)行 halt 指令。
          實際上,對于個人計算機(jī)來說,halt 可能是 CPU 執(zhí)行最多的一條指令,全世界的 CPU 大部分時間都用在這條指令上了,是不是很奇怪。
          更奇怪的來了,有的同學(xué)可能已經(jīng)注意到了,上面的循環(huán)可以是一個while(1) 死循環(huán),而且這個循環(huán)里沒有break語句,也沒有return,那么操作系統(tǒng)是怎樣跳出這個循環(huán)的呢?
          關(guān)于這個問題,我們將會在后續(xù)文章中講解。

          總結(jié)
          CPU 空閑時執(zhí)行特定的 halt 指令,這看上去是一個很簡單的問題,但實際上由于 halt 是特權(quán)指令,只有操作系統(tǒng)才可以去執(zhí)行,因此 CPU 空閑時執(zhí)行 halt 指令就變成了軟件和硬件相結(jié)合的問題。
          操作系統(tǒng)必須判斷什么情況下系統(tǒng)是空閑的,這涉及到進(jìn)程管理和進(jìn)程調(diào)度,同時,halt 指令其實是放到了一個 while 死循環(huán)中,操作系統(tǒng)必須有辦法能跳出循環(huán),所以,CPU 空閑時執(zhí)行 halt 指令并沒有看上去那么簡單。
          希望這篇文章對大家理解 CPU 和操作系統(tǒng)有所幫助。


          技術(shù)交流,歡迎加我微信:ezglumes ,拉你入技術(shù)交流群。

          推薦閱讀:

          音視頻面試基礎(chǔ)題

          OpenGL ES 學(xué)習(xí)資源分享

          開通專輯 | 細(xì)數(shù)那些年寫過的技術(shù)文章專輯

          NDK 學(xué)習(xí)進(jìn)階免費視頻來了

          推薦幾個堪稱教科書級別的 Android 音視頻入門項目

          覺得不錯,點個在看唄~


          瀏覽 53
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久久久无码精品人妻 | 日韩黄色一级电影 | 青青草成人在线男人的天堂 | 丁香5月激情 | 啪啪免费网站 |