現代操作系統的內核線程調度是什麼方式,和CPU使用率什麼關係?

CPU使用率是如何計算的呢?一般情況下如果一個線程結束了,只需要分配CPU給下一個就好了啊,不會存在中間什麼都不做的空狀態的吧,那佔用率應該是100%啊?


題主說的情況基本不會遇到。現代操作系統雖然都是 preemptive multitask。但是 99.99% 的情況下是一個進程 voluntarily relinquish CPU。比如說,一個進程讀 disk 的時候,控制權就交給 disk controller 了,這時進程就被掛起了,直到 disk controller 告訴操作系統任務完成,這個進程才會再參與到 schedule 中。

在 95% 以上的時間裡,系統里的所有進程都是被掛起的:都在等待某個外圍設備。現代操作系統中很少有進程發起全力計算兩分鐘以上的,對於 MBP 來說,這個時候風扇就已經開始高速了。

CPU 的使用率:CPU 是不存在「什麼都不做」的狀態的。當所有進程都掛起的時候,操作系統會運行內核里的一個零號進程。這個進程佔用 CPU 的百分比就是系統的 idle 率。在古老的 386 里,這個零號進程就是空循環。後來有了高級電源管理,這個零號進程就是調用高級電源管理的功能讓 CPU 降頻等等,把發熱降下來。


樓主的問題描述有些不清晰,我來總結一下你的問題:

1)如果系統中由兩個以上的未結束線程,那麼CPU不會處於空閑態?

2)CPU是按照時間片進行調度的,一個線程的時間片用完以後,就會切換到下一個進程?

3)既然是按照時間片來調度,那麼為何我們在播放音樂的時候,感覺不到某個線程的停頓?

問題:CPU會不會空閑?

首先,對於問題1,應該區分線程空閑和CPU空閑本質上是兩個事情。如果樓主使用的是linux系統,可以查看/pro/stat下面的數據:

hyk@hyk-pc:~/doc/zhihu$ cat /proc/stat

cpu 83354 334 53262 201868 1122 0 34 0 0 0

cpu0 17994 190 16228 49495 691 0 30 0 0 0

cpu1 17943 18 14140 52669 111 0 0 0 0 0

cpu2 26525 18 10393 48140 188 0 1 0 0 0

cpu3 20890 107 12500 51563 131 0 1 0 0 0

這裡面顯示的是CPU在系統時間、用戶時間、空閑時間、IO等待時間等方面消耗的時間片.回到樓主的問題,CPU會不會空閑?答案是會!從宏觀上講,如果進程在等待磁碟讀寫、網卡數據等,都會造成CPU空閑;從圍觀上講,如果CPU執行了nop指令,比如sleep函數,也會導致cpu空閑。一個系統中的真正活躍進程並不多,所以會由cpu使用率並不高的情況。

問題:線程/進程如何根據時間片切換?

第一,一個進程運行的時候,如果發生了阻塞,即使時間片沒有用完,也會進行切換;

第二,對於帶有優先順序的進程調度演算法,即使當前時間片用完,進程的分配時間片如果還有剩餘,也不會發生切換。

所以一個線程的時間片用完之後,切換到下一個時間片,這個說法不嚴謹。

問題:為何我們感受不到音樂線程的暫停?

首先,我們要弄清楚一件事情,音樂是由音效卡來播放的,不是由CPU來播放的;所以CPU僅僅需要做好控制工作,將數據發送給音效卡驅動就可以了,播放music,其實和CPU沒有太大的關係。

其他:1)系統負載和CPU利用率的關係?

目前的負載評價手段,雖然由很多,但主要的是運行隊列中的進程數目,這個你可以調用uptime來查看。即使只有一個程序,比如核心代碼是

while(true){

a++;

}

那麼這個程序將會導致CPU的利用率是100%;但是這個CPU的負載並不高。但是如果你的CPU需要運行很多進程,而且這些進程又都處在就緒態,那麼這個CPU負載就很高了。

2)SMP下的進程調度

在現代計算機上,又很多CPU,目前的調度演算法是如果某個CPU的負載超過最低CPU負載的25%,那麼將發生進程遷移。當然,你也可以講某個線程綁定在某個CPU上。

實踐:《編程之美》上有一道題目:如果編寫程序講CPU的利用率曲線變成一個正弦曲線,不妨試一試,就能理解很多問題了。


先簡單回答一下:

以linux來講, 不管個人桌面還是sever端, 都不太可能有100個以上的物理線程.

其次, linux的"時間片"默認是4ms.

如何保證每個進程的運作近似連續的?

沒辦法三言兩語說清楚, 簡單說就是每個線程輪流運行.

一般情況下如果一個線程結束了,只需要分配CPU給下一個就好了啊.

還有負載均衡的問題, 比較複雜.

不會存在中間什麼都不做的空狀態的吧,那佔用率應該是100%啊?

簡單說, 會的, 所以使用率不會一直是100%.

請參考 @馮東 的答案.

現在虛擬化技術很常見了, 這種情況下統計各任務cpu準確使用率比較複雜, 不細講.

-------------------------

任務調度其實重點就是計算優先順序(權重)的策略不同而已,優先順序的策略不同導致了時間片分配策略不同。os分配時間片時還要考慮虛擬化的因素。細節搜vruntime

數據結構linux內核cfs用rbtree實現優先隊列,rt調度用雙向鏈表。有些用戶態job scheduler也有用graph,其實基本就是實現優先隊列。軟實時硬實時啥的我就不扯了,自己google

調度策略就主動sleep/sche_yield,或者被動等kernel每次硬中斷時統一處理work queue(linux默認是4ms)。

切換時不同的task實現需要保存的context(簡單理解為結構體)不同而已,比如linux的task_struct(內嵌thread_info標識線程),lua的lua_state,erlang的 process等等。

概念上, 進程比線程多了切換頁表的開銷.

userland task優點是沒有進出內核的切換開銷, 缺點是需要自行實現任務調度和context管理, 一般人都使用庫或者原生支持userland task的語言.

掃盲看看Schedule


題主舉的例子很理想化。

假如單核,同時有50個進程線程處在運行狀態,如果這些進程執行過程中一直不會因為等待資源(硬碟、網路、感測器等)進入阻塞態,只會因為時間片用完了進入就緒態。

那此時linux下cpu佔用率是100% ,負載高達50 。 就不要想太多了。

事實上,單核只要一個這樣的線程,就能把cpu佔用率搞到100%了。

這樣的線程也很好寫, while(1) ; 就ok。只要線程優先順序夠高。

另一個問題,是媒體播放器如何做到流暢的? 簡單說這樣的音頻視頻網路控制器都會有自己的硬體緩衝區,就像水庫那樣,緩衝區里有數據,控制器就能持續輸出。只要程序在佔有時間片時,準備好了足夠多的數據,自己搬或者稍後用dma搬到控制器自己的緩衝區里,就能保證不斷流了。


1000個進程,100個最高優先順序(並且是就緒狀態),確實多了。不管怎樣,按這個討論。

Linux上現在預設用的CFS(完全公平調度器),時間片的長度是會變的。沒修改過的話,是從0.75ms到6ms。進程數,也是影響時間片長度的因素之一。所以,即使有100個,輪到的一次的時間,也沒那麼長。

另外,任何線程做阻塞的系統調用,就放棄當前的時間片了。系統里的多數進程,其實都在等用戶的輸入;在用戶有新的輸入之前,系統調用不會返回,它也就不會得到新的時間片。也就是說,真正就緒狀態的線程不會太多的。

至於音樂播放器,流暢播放和時間片之間的間隔沒有太大關係。只要每個時間片里準備的音樂數據,超過時間間隔,就可以了。剩下的就是音效卡處理了。

系統里還會有idle進程。其他所有進程都沒有就緒的時候,就會執行它。執行它的時間是不會統計到CPU佔用率裡面的。


推薦閱讀:

微軟這些年有哪些大的敗筆?
關於小米筆記本用linux系統?
就內存管理而言 Linux 系統相對於 Windows 有哪些優勢?
現在哪些編程語言適合寫操作系統?
如果讀取硬碟上某個文件,使用完畢後釋放內存,然後立即再讀取這個文件,會從內存中還是從硬碟上再讀取?

TAG:MicrosoftWindows | 操作系統 | Linux | 線程 | 操作系統內核 |