進程是正在運行的程式的實例,它可以包含一個或多個線程。我們瞭解了進程的執行方式,包括早期單核處理器上的順序執行以及引入多任務概念實現的偽並行。我們還探討了進程的狀態模型。進程可以處於就緒、運行、阻塞和結束等不同的狀態。就緒狀態表示進程已經準備好運行,但還沒有被調度執行。運行狀態表示進程正在執行。阻塞... ...
進程
所謂進程,大家可以理解為我們打開的應用程式,如微信、QQ、游戲等,但也有系統應用是我們看不見的,可以打開任務管理器一探究竟,我們寫的代碼程式在伺服器上在不運行的情況下,它就是一個二進位文件,並不是進程!
一個進程可以包含一個或者多個線程,但對於CPU來說他就是一個任務而已;
在早期,我們的CPU只有一個,而有多個任務需要執行時,它們只能排隊等待,無論前面的任務執行時間有多長,後面的任務都得耐心等待。這種方式顯然存在明顯的弊端。舉個例子,假設排在前面的A任務需要執行1小時,而排在後面的B任務僅需1分鐘,那麼B任務必須等待A任務完成後才能執行,這種方式顯得極其不靈活。
進一步發展後,我們擁有了多任務的系統。在CPU在同一時間只能處理一個任務的前提下,系統將時間劃分為多個時間片,每個任務只能占用一個時間片來執行自己的任務。一旦時間片用完,就必須輪到下一個任務執行,這種方式看起來就像是多個進程或任務同時在運行,這就是我們所說的併發,也稱為偽並行。
有偽並行,那麼就有真並行,隨著現代化發展,我們的CPU開始擁有多核處理器,如4核、8核等。這樣每個核心就像一個獨立的CPU一樣,可以並行處理多個任務。,8核對應的就是8個任務並行處理;
然而,我們當前的伺服器系統都是高併發狀態,不僅要運行自己的業務,還要占用一定的CPU資源來運行系統進程。因此,以下一系列問題就出現了:
- 一個任務占用多長時間的時間片?
- CPU如何進行任務切換?當一個任務正在執行時被切換,資源如何處理?
- CPU如何找到下一個要執行的任務的位置?
進程的狀態
五狀態模型
當我們的程式啟動後就會變成這種狀態,關聯如下:
就緒->運行:當任務獲得時間片後,使用CPU執行操作,進入運行狀態。
運行->阻塞:進程調用系統服務時,無法立即獲取返回值(如IO操作),進入阻塞狀態。
運行->就緒:如果占用的時間片已經結束了,但任務未完成,回到就緒狀態。
阻塞->就緒:阻塞結束後,進程回到就緒狀態。
運行->結束:進程自行完成任務後,那麼會被系統終止;
以上便是對於單個進程的5狀態描述,從上面可以看出由於系統通常同時運行多個進程,因此就緒和阻塞狀態的進程可能會有多個,那麼這麼多進行都在就緒態和阻塞態怎麼辦?一般來說就是使用隊列,這不跟你寫java是一樣的解決方案嗎?排隊就行了
七狀態模型
隊列是可以解決排隊了問題了,但是這麼長的隊列放到哪裡呢?我們的記憶體是很寶貴的,所以這裡面就有上一節說的記憶體交換的問題了,可以使用記憶體交換機制將部分進程交換到磁碟中,這時候就是一個掛起的狀態;
掛起的狀態分兩種:
- 就緒狀態的掛起:一旦進程重新載入到記憶體中,就會立即運行。
- 阻塞狀態的掛起:等待特定事件發生後才會運行。
這時候你就知道為什麼你可以運行很多個程式,但是有時候你打開的太多了,你正打開某一個軟體的同時,另一個軟體自己退了,你就可以看下你的記憶體是不是滿了,這是因為已經被交換到磁碟中的進程不容易重新載入回記憶體。一旦記憶體已滿,重新載入進程就變得困難。
總結
進程是指正在運行的程式,可以包含一個或多個線程。在早期,CPU只有一個核心,多個任務需要排隊等待執行。後來,引入了多任務的概念,將時間劃分為多個時間片,每個任務占用一個時間片執行,實現了偽並行。現代CPU擁有多核處理器,可以並行處理多個任務。高併發的伺服器系統中,除了運行業務,還要占用一定的CPU資源運行系統進程。進程的狀態通過隊列進行管理。同時還討論了記憶體交換和進程掛起的問題。