計算機系統009 - 操做系統之進程

上一篇計算機系統008 - 操做系統概況中講到,計算機操做系統發展的兩個主要方向是提升CPU使用率,以及下降響應時長。這二者在微觀調度方法一級來看是相互違背的,但從宏觀調度策略來說,仍是能夠作出折中的利弊權衡。固然,並不是全部計算機系統都追求所謂的平衡,不少時候特定領域的系統更重視高實時響應,而有的場景只須要儘量利用CPU計算能力便可。 數據結構

方向決定方法,對於進程的理解,就從這兩個目標開始。 多線程

1. 進程

進程這個概念突然跳出來,略顯突兀,但是不少資料上就這麼天然地放在這裏。爲了更好地理解進程概念的由來,這裏先對照計算機系統發展史來講明一下。 異步

1.1 進程的由來

最先的時候,也就是單處理器時期,系統要執行一個計算任務的步驟是將整個程序加載到內存中,而後由CPU逐條讀取並執行指令。程序包括代碼指令和預約的數據,指令執行期間,確定會產生一些計算結果,部分爲臨時使用。因此天然而言,寄存器中應當保存一部分臨時值,舉個例子,加法器執行一個加法運算,寄存器中就須要存儲CF進位信息。那麼總的來說,一個程序運行後,至少會包含以下信息: 模塊化

  • 程序代碼
  • 數據集
  • 運行時信息

這個時期中計算機系統的計算時間主要經過預定或批處理系統監控獲取,所存在的最大問題是CPU和I/O運行速率量級相差太大,CPU的速率遠遠高過I/O速率,致使一旦執行到I/O指令時,系統中CPU資源就處於閒置狀態,而指令每次執行,又至少會涉及到一次內存地址的訪問。也就是說,系統運行期間,CPU資源被大量浪費post

爲了提高CPU資源使用率,下降計算成本,可行的主要方法是加載更多的程序到內存中,一旦某個程序要執行I/O操做,就切換到其餘程序運行。固然這裏可以切換的前提是,I/O具體操做由其餘單元進行控制,只需少許CPU執行先後準備、收尾工做便可,典型的有DMA直接內存訪問。既然涉及到程序切換,那就勢必要對一個運行中程序的全部相關信息進行統一管理,這樣才能以該單位進行切換避免出錯,而這裏,這個單位就叫作進程。 操作系統

1.2 進程狀態

前面講了將內存中運行中的程序也就是進程進行切換,來達到提高CPU利用率的目的。既然有切換,也就意味着至少有運行、非運行兩種狀態。在該粒度控制下,CPU能夠在多個程序間進行切換,避開I/O操做的閒置指令週期,提高總體使用率。 線程

然而上面的調度只是粗粒度的,任什麼時候候,要想作出更精確的決定,就必須基於更多的有效信息。對於操做系統來說,要想更精確地在不一樣進程間切換CPU,就必須掌握更多進程的有效信息,而增長信息的第一步,就是下降粒度,細化進程狀態的分類。例如對於非運行狀態而言,它難以對新建立的進程和處於I/O等待過程當中的進程作區分,這樣一來,將處於I/O等待過程當中的從新運行就純屬對CPU資源的浪費行爲。 設計

在上述兩種狀態的基礎上,現代操做系統一般會區分爲以下幾種狀態:
指針

  • 新建態
  • 就緒態
  • 掛起態(可選)
    添加掛起態的根本緣由是每多加載一個進程進入內存空間就多了一個選擇,就能夠更大程度地避開I/O等待,有效利用CPU資源。但因爲物理內存有限,致使能加載入內存的進程數量也有限。爲了擁有更多可選擇進程,就經過將一部分處於I/O等待過程當中的進程從內存空間寫出到磁盤空間,當須要從新調度被寫出進程時,再從磁盤空間從新讀取。
    固然也存在其餘方法去下降一個進程所需的物理內存,如基於頁交換硬件支持,來實現只加載進程的必要信息而非所有內容來實現下降內存佔用。這一部分會再後面的內存管理進一步介紹。 cdn

    • 阻塞/掛起態
    • 就緒/掛起態
  • 阻塞/等待態
    進程在某些事件發生前不能繼續執行,如I/O操做完成事件。
  • 運行態
  • 退出態

1.3 進程調度

以下圖所示,內存(虛擬內存)中進程總體構成以下。進程狀態屬於進程運行時信息中的一部分,現代操做系統中比較通用的運行時狀態信息是一個稱爲進程控制塊PCB(Process Control Block)的結構體。

PCB中主要含有三類信息:

  • 進程標識信息
    表示信息主要指標識符,包括進程ID(PID)、父進程ID、用戶ID(UID)

  • 進程狀態信息
    包括用戶可見寄存器、控制和狀態寄存器、棧指針三個子類型數據,一般CPU設計中存在一組稱爲程序狀態字PSW(Program Status Word)的寄存器,它包含條件碼和其餘狀態信息。

    以Intel X86爲例:

  • 進程控制信息
    包括調度和狀態信息(如優先級、事件等)、數據結構、進程間通訊、進程特權、存儲管理、資源的全部權和使用狀況等。

而所謂的各類狀態進程隊列,實際上都是以鏈表形式管理各進程PCB數據結構。

至此咱們知道,進程由代碼、數據、棧、運行時信息組成,進程概念的提出主要是便於調度管理,其中所包含的運行時信息能夠爲調度方法提供有效信息。而調度自己又是經過在處於不一樣狀態的進程間切換以避開I/O等待,從而達到提升CPU利用率的目的。

2. 線程

上一節中咱們從整個操做系統的角度來討論了進程概念的由來和必要性,同時也提到,在具有更多有效信息的基礎上,更小粒度的控制能夠達到更加精確的調度結果,從而充分利用CPU。那麼對於每個進程而言,是否有方法能夠達成更精細的控制?

答案就是線程。

2.1 線程概念

突然又跳出來一個名詞,線程。從字面來看,也看不出什麼,只好記住一個概念,線程是對進程進行更小粒度的細分。對於單處理器單核系統來說,每次只能運行一個進程,即便進行了更小粒度的細分,也並不能在總體上加快進程運行速度,甚至有可能因爲頻繁切換而引入更多的消耗。 但考慮實際應用中,每一個程序代碼中可能存在對於多個硬件部件的操做,如一部分進行內部數據計算、一部分負責文件讀寫、一部分負責顯示刷新,最後一部分負責與用戶交互

這裏的用戶交互使用了粗體進行強調,的確,單CPU單核狀況下,只能經過不斷切換進程內部執行的指令來提供良好的交互響應。例如,對程序代碼進行兩個部分的劃分,一個部分負責文件讀寫,一部分負責與用戶交互。每一個部分以一個線程形式運行,經過將CPU在進程內部的兩個線程間切換,達到執行慢I/O操做的同時,也能插入執行用戶交互代碼。這樣一來,在有限的硬件資源狀況下,也必定程度下降了平均響應時長

對於單核來說,可能見效通常,可是對於多處理器多核來說,將每個線程分配各同一CPU種的多核後,那就是並行執行多個線程,總體所需時長也將降低。從用戶的角度來說,一樣是下降了程序執行所需平均時長

因此綜合來看,線程在單核系統上中能夠有效下降平均響應時長,在多核系統上,經過並行,能夠有效下降總體時長。爲了達成精確調度,與進程同樣,線程也應該維護運行時信息。一般多線程技術適用於以下使用場景:

  • 前臺和後臺工做
  • 異步處理
  • 提升執行速度
  • 模塊化程序結構

2.2 與進程關係


如上圖所示,一個進程中至少含有一個線程(也稱爲主線程),固然也能夠根據程序特性選擇使用多線程技術。存在多個線程時,線程間相互共享進程用戶地址空間。

什麼意思?換句話就是說,假如內存是整個街道,那麼進程就是一套套房子,每套房子相互之間共享道路等資源,就像進程在操做系統中共享總線同樣。若是進程是房子,那麼線程就是房子中的房間,各有各的戶型。房間之間相互共享房子內公共資源,如廚房、衛生間等,固然每一個房間自己也存在必定內部資源,僅供本身使用。

若是房子建立了,那麼確定至少會建立一個房間。若是房子銷燬了,那麼內部全部房間也天然被銷燬。

2.3 線程支持級別

線程的實現上分爲用戶級(ULT, User Level Thread)和內核級(KLT, Kernel Level Thread)兩種。

  • 用戶級
    線程管理全部工做在應用程序內完成,內核意識不到線程的存在。即應用程序自己擁有絕對自主權,它能夠根據程序特色自由使用線程管理策略,同時,也避免了因爲某些操做系統內核不支持多線程而沒法使用線程技術。
    但因爲內核未進行支持,內核仍以進程爲單位對程序進行調度。所以在線程中調用操做系統API時,一旦發生阻塞,則整個進程都將被阻塞。

  • 內核級
    對應的有,內核級線程中線程管理工做所有由內核完成,應用程序只須要提交任務爲線程便可。與用戶級線程相比,內核掌握了更多線程相關信息,能夠將同一個進程調度到不一樣處理器中,某一個線程的阻塞也再也不會阻塞整個進程。
    但因爲應用程序進程仍處於用戶模式,而線程處於內核模式,所以再講控制從一個線程傳送到同一個進程的另外一個線程時,須要進行狀態切換。

因爲各有優劣,某些操做系統就混合使用了用戶級、內核級線程,在混合方法中,線程在用戶空間中建立、調度,但也能夠託管一部分給內核調度。經過在程序級別與硬件進行匹配,達到最合適的效果。

3. 總結

本篇主要從提升CPU利用率和下降平均響應時長兩個角度來分析了進程、線程概念的由來和必要性,它們均只是內存中的調度單位,建立進程或線程的目的是便於進行下一步的並行執行,也就是在分配給多個CPU或多核或是單核上,按照必定策略調度執行。下一篇中將從並行設計開始提及,看看切換過程當中要注意哪些事項。

相關文章
相關標籤/搜索