咱們常常說的平均負載和cpu升高沒有直接的關係,在不一樣的場景cpu升高會致使系統負載,可是系統負載不必定是cpu升高致使的。linux
io密集型進程,等待io也會致使平均負載升高,但cpu不必定很高。緩存
大量進程競爭cpu(也就是上面的第三個場景),每每是被忽略的,cpu雖然沒有使用,只是在競爭,也會發生負載嗎?微信
咱們都知道linux是一個多任務操做系統,它支持遠大於cpu數量的任務同時運行,固然這些任務不是同時運行,而是系統在很短期內,將cpu輪流分配給它們,形成多任務同時運行的錯覺。而每一個任務運行前,cpu須要知道任務從哪裏加載、又從哪裏開始運行,也就是說,須要系統事先幫它設置好cpu寄存器和程序計數器。多線程
cpu內置的容量小、但速度極快的內存。ide
是用來存儲cpu正在執行的指令位置、或者即將執行的下一條指令位置。他們都是cpu在運行任何任務前,必須的依賴環境,所以也被叫作cpu上下文。函數
cpu上下文切換:就是先前一個任務的cpu上下文(也就是CPU寄存器和程序計數器)保存起來,而後加載新任務的上下文到這些寄存器和程序計數器,最後再跳轉到程序計數器所指的新位置,運行新任務。性能
而這些保存下來的上下文,會存儲在系統內核中,並在任務從新調度執行時再次加載進來。這樣就保證原來任務的狀態不受影響,讓任務看起來仍是連續運行。操作系統
根據任務不一樣,cpu的上下文切換就能夠分爲不一樣的幾個場景,進程上下文切換,線程上下文切換以及中斷上下文切換。線程
linux安裝特權等級,把進程的運行空間分爲內核空間和用戶空間對象
![]
內核空間(Ring0)具備最高權限,能夠直接訪問全部資源;
因此,進程既能夠在用戶空間運行又能夠在內核空間運行,在用戶空間運行時,稱爲用戶態。在內核空間運行時,稱爲內核態。
系統調用:cpu寄存器裏面原來的用戶態的指令位置,須要先保存起來。接着,爲了執行內核態代碼,cpu寄存器須要更新爲內核態指令的新位置。最後,才跳轉到內核態運行內核任務。
進程是由內核來管理和調度的,進程的切換隻能發生在內核態,因此,進程的上下文不只包括了用戶態的虛擬內存,用戶棧,全局變量等資源。還包括了內核棧、寄存器等內核空間的狀態。
所以,進程的切換比系統調用多了一步:在保存當前進程的內核狀態和cpu寄存器以前,須要先把用戶態的虛擬內存,用戶棧保存下來;在加載了下一進程的內核態後,須要刷新進程的虛擬內核和用戶棧。
保存上下文和恢復上下文的進程並非免費的,須要內存在cpu上運行才能完成。
每次上下文切換都須要幾十納秒到微妙的cpu時間。這個時間仍是至關可觀。在進程上下文切換次數較多的狀況下,很容易致使cpu將大量時間耗費在寄存器、內核棧以及虛擬內存等資源的保存和恢復上,進而大大縮短了真正運行進程的時間。這也是致使平均負載升高的重要因素。
linux經過(tlb)來管理虛擬內存和物理內存直接的映射關係,當虛擬內存更新後,tlb也要更新,內存訪問隨之變慢。特別是在多處理器系統上,緩存被多個處理器共享,刷新緩存不只影響當前處理器的進程,還會影響共享緩存的其餘處理器的進程。
進程執行完終止了,會釋放cpu,這個時候cpu從就緒隊列裏面拿一個新的進程運行,還有其餘的一些非正常場景也會致使進程切換。
時間片耗盡:爲了保證因此進程能夠獲得公平調度,CPU時間被劃分紅一段段的時間片,這些時間片輪流分配給各個進程。當某個時間片耗盡了,就會被系統掛起,切換到其餘等待cpu的進程運行。
系統資源不足(如:內存不足):這個時候進程會被掛起,並由系統調度其餘進程運行。
進程主動掛起: 當進程經過睡眠函數sleep這樣的方式將本身主動掛起時。
高優先級進程:當有優先級高的進程出現時,爲了保證優先級高的進程運行,當前進程會被系統掛起
硬件中斷時:當發生硬件中斷時,Cpu上的進程會被中斷掛起,轉而執行內核中的中斷服務程序。
線程和進程最大的區別在於,線程是調度的基本單位,而進程則是資源擁有的基本單位。所謂內核中的任務調度,實際上的調度對象是線程;而進程只是給線程提供了虛擬內存、全局變量等資源。因此,對於線程和進程能夠理解爲:
當進程只有一個線程時,能夠任務進程就是線程。
當進程擁有多個線程時,這些線程共享相同的虛擬內存、全局變量等資源。這些資源在上下文切換時是不須要修改的。
因此說:
當兩個線程不屬於同一進程時,線程上下文切換時。由於資源不共享,因此切換就至關於時進程間切換。
當兩個線程屬於同一進程時,線程上下文切換時。由於資源共享,只須要切換線程私有數據。
進程間切換消耗的資源多於線程間切換,因此就出現了多線程代替多進程的優點。
爲了快速響應硬件的事件,中斷處理會打斷進程的正常調度和執行,轉而調用中斷處理程序,響應設備事件。在打斷其餘進程時,就須要將進程當前狀態保存起來。
跟進程上下文切換不一樣是,中斷上下文切換不會涉及到進程的用戶態。因此,即使中斷過程打斷了一個用戶態的進程,也不須要保存和恢復進程的虛擬內存。全局變量等用戶態資源。中斷上下文,其實只包括內核態中斷服務程序執行必須的狀態,包括cpu寄存器、內核堆棧、硬件中斷參數等。
對同一個cup來講,中斷處理比進程擁有更高的優先級,因此中斷上下文切換並不會與進程上線文切換同時發生。因此大部分中斷處理程序都短小精悍,以便儘快的執行結束。
總結