《Windows內核原理與實現筆記》(四)Windows進程線程概念

進程概念

進程是各種資源的容器,它定義了一個地址空間作爲基本的執行環境;而線程是一個指令執行序列,它可以直接訪問所屬進程中的資源。每個進程都至少有一個線程,而每個線程在任一時刻都一定屬於某一特定的進程。

多進程模型

把時間細分,然後在某個適當的時間粒度上輪流執行這些任務,讓每個任務都有機會被執行到。只要在人所能感知的時間粒度上(差不多是100~200ms)每個任務都有機會做一點事情,用戶就會認爲這些任務是同時在執行。這種並行也被稱爲僞並行,而這樣的系統被稱爲分時系統。有時候,計算機可能配有多個處理器,僞並行也有可能變成真並行。

每個進程都有自己的運行時間軸,感覺就像在一個單獨的處理器上運行一樣。系統負責切換這些進程,讓它們得以輪流執行。系統通過某種硬件機制或軟件機制獲得控制權,保留好這個進程的環境信息,包括內存空間、寄存器和指令流信息,然後挑選下一個要被執行的進程,恢復此進程的環境信息,並把控制權交給它,由它使用下一個時間片段。

操作系統需要做的事情是:維護一個全局的進程表,記錄下當前有哪些進程正在被執行;把時間分成適當的片段,可以通過設置時鐘中斷來完成,因而每次時鐘中斷到來時系統就會獲得控制權,在進程間實施切換。

一個C/C++程序的典型佈局結構如下:

內存區域有三種類型:靜態數據區、動態數據區,以及維護控制流信息和局部狀態的調用棧區域。 

關於操作系統如何控制進程的創建和終止,首先,操作系統在引導過程中,必須把系統運行所必要的進程全部創建起來。所謂創建一個進程是指建立起基本的進程執行環境,然後把它加入到系統的全局進程表中,使它有機會得到處理器時間和其他系統資源,操作系統會創建一組初始的進程,這是在系統引導時完成的。

其次進程在必要時候可以請求系統幫他傳教一個進程,也可以爲了響應用戶創建一個新進程。

進程完成操作之後,可以通知操作系統終止,當一個進程完成了所有預定的功能以後,它的使命便已結束,最後的職責是通知操作系統,自己要終止了。操作系統接到請求以後,清理掉這個進程所佔據的各種資源,使它們能被回收,並且將該進程從系統的全局進程表中移除,在現代操作系統結構中,進程可以有多個控制流,每個控制流對應一個調用棧。操作系統在創建進程時僅建立一個控制流,但是在該控制流的執行過程中,它又可以創建額外的控制流,這樣便形成了一個進程多個控制流的情形。

線程概念

線程不僅僅是一個控制流,它還有更多的內容。線程的調用棧(call stack)記錄了它作爲控制流的狀態信息,包括每一層函數調用和返回的指令地址。線程一定隸屬於某個進程,其控制流可以訪問這個進程中的資源,包括所有的內存數據以及系統分配給此進程的其他資源。

線程模型

在現代計算機結構中,先後提出過兩種線程模型:用戶級線程(user-level threads)和內核級線程(kernel-level threads)。

所謂用戶級線程是指,應用程序在操作系統提供的單個控制流的基礎上,通過在某些控制點(比如系統調用)上分離出一些虛擬的控制流,從而模擬多個控制流的行爲。用戶級線程模型的優勢是線程切換效率高,因爲它不涉及系統內核模式和用戶模式之間的切換;另一個好處是應用程序可以採用適合自己特點的線程選擇算法,可以根據應用程序的邏輯來定義線程的優先級,當線程數量很大時,這一優勢尤爲明顯。但是會增加複雜度。

用戶級線程模型的優勢是線程切換效率高,因爲它不涉及系統內核模式和用戶模式之間的切換;另一個好處是應用程序可以採用適合自己特點的線程選擇算法,可以根據應用程序的邏輯來定義線程的優先級,當線程數量很大時,這一優勢尤爲明顯。

內核級線程往往指操作系統提供的線程語義,由於操作系統對指令流有完全的控制能力,甚至可以通過硬件中斷來強迫一個進程或線程暫停執行,以便把處理器時間移交給其他的進程或線程。所以,內核級線程有可能應用各種算法來分配處理器時間。處理器的時間通常是按線程而非進程來分配,因此,系統有必要維護一個全局的線程表,在線程表中記錄每個線程的寄存器、狀態以及其他一些信息。然後,系統在適當的時候掛起一個正在執行的線程,選擇一個新的線程在當前處理器上繼續執行。內核級線程的好處是,應用程序無須考慮是否要在適當的時候把控制權交給其他的線程,不必擔心自己霸佔處理器而導致其他線程得不到處理器時間。

內核級線程切換是個問題,因爲涉及到用戶模式切內核模式,但是現在cpu這部分時間可以接受。

線程的創建和刪除也是一個重要的考慮指標。當應用程序或系統進程需要的線程數量可能比較多時,通常可採用線程池技術作爲一種優化措施,以降低創建和刪除線程以及線程頻繁切換而帶來的開銷。

在支持內核級線程的系統環境中,進程可以容納多個線程,這導致了多線程程序設計(multithreaded programming)模型。由於多個線程在同一個進程環境中共享了幾乎所有的資源,所以,線程之間的通信要方便和高效得多,這往往是進程間通信(IPC,Inter-Process Communication)所無法比擬的,但是也很容易使線程之間因同步不正確而導致數據被破壞,而且,這種錯誤存在不確定性,因而相對來說難以發現和調試。

線程調度算法

如果一個操作系統支持內核級線程,那麼處理器資源的調度通常在線程而非進程粒度上進行。

一個線程調度算法要考慮公平性,CPU的有效利用。

從大的分類來講,調度算法可以分爲非搶佔式算法和搶佔式算法。在非搶佔式系統中,一個線程一旦被選擇在處理器上運行,就將一直運行下去,直到阻塞(比如等待I/O或等待一個信號量)或者自願放棄或退出。在搶佔式系統中,一個線程被選中在處理器上運行以後,允許運行的時間長度有最大限制,一旦達到了這麼長時間,就將被迫放棄執行權,交由系統挑選其他的線程來運行,或者若找不到其他的線程,則再把執行權交還給它,讓它繼續運行。搶佔式調度算法需要一個時鐘中斷來獲得對處理器的控制權,而非搶佔式算法並不需要時鐘中斷。

典型的線程調度算法有(1) 先到先服務算法。(2) 時間片輪轉調度算法。(3) 優先級調度算法。

Windows的調度算法是一個搶佔式的、支持多處理器的優先級調度算法,它爲每個處理器定義了一個鏈表數組,相同優先級的線程掛在同一個鏈表中,不同優先級的線程分別屬於不同的鏈表。當一個線程滿足了執行條件時,它首先被掛到當前處理器的一個待分配的鏈表(稱爲延遲的就緒鏈表)中,然後調度器會在適當的時候(當它獲得了控制權時)把待分配鏈表上的線程分配到某個處理器的對應優先級的線程鏈表中。當這個處理器在選擇下一個要運行的線程時,會根據優先級準則選擇此線程(如果沒有同等或更高優先級的線程也在等待運行的話)。Windows中線程的優先級調整考慮到了很多因素,例如前臺線程、等待I/O完成後的線程也有輕微的優先級提升,這是一些來自實踐經驗的設計細節,它們使得Windows操作系統對於交互式應用程序有更好的性能表現。

 

發佈了168 篇原創文章 · 獲贊 17 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章