天天看點

《Windows核心原理與實作筆記》(四)Windows程序線程概念程序概念線程概念 

程序概念

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

多程序模型

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

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

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

一個C/C++程式的典型布局結構如下:

《Windows核心原理與實作筆記》(四)Windows程式線程概念程式概念線程概念 

記憶體區域有三種類型:靜态資料區、動态資料區,以及維護控制流資訊和局部狀态的調用棧區域。 

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

其次程序在必要時候可以請求系統幫他傳教一個程序,也可以為了響應使用者建立一個新程序。

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

線程概念

線程不僅僅是一個控制流,它還有更多的内容。線程的調用棧(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作業系統對于互動式應用程式有更好的性能表現。

繼續閱讀