作業系統中的程序與執行緒

2022-01-17 07:49:24 字數 3640 閱讀 5739

如果非要說是為什麼需要執行緒,還不如說為什麼需要程序中還有其它程序。這些程序中包含的其它迷你程序就是執行緒。

執行緒之所以說是迷你程序,是因為執行緒和程序有很多相似之處,比如執行緒和程序的狀態都有執行,就緒,阻塞狀態。這幾種狀態理解起來非常簡單,當程序所需的資源沒有到位時會是阻塞狀態,當程序所需的資源到位時但cpu沒有到位時是就緒狀態,當程序既有所需的資源,又有cpu時,就為執行狀態。

下面我們來看乙個具體的例子:

就拿我寫部落格的livewriter來說,livewriter需要監聽我打字輸入的狀態,還需要每隔5分鐘對草稿進行自動儲存。假設如果這個程序只有乙個執行緒的話,那麼當對草稿進行儲存時,因為此時需要訪問硬碟,而訪問硬碟的時間執行緒是阻塞狀態的,這時我的任何輸入都會沒有響應,這種使用者體驗是無法接受的,或許我們可以通過鍵盤或者滑鼠的輸入去中斷儲存草稿的過程,但這種方案也並不討好。而使用多執行緒,每個執行緒僅僅需要處理自己那一部分應該完成的任務,而不用去關心和其它執行緒的衝突。因此簡化了程式設計模型。如圖1所示。

圖1.兩條執行緒滿足各自的功能

更具體的說,執行緒的好處如下:

1.在很多程式中,需要多個執行緒互相同步或互斥的並行完成工作,而將這些工作分解到不同的執行緒中去無疑簡化了程式設計模型。

2.因為執行緒相比程序來說,更加的輕量,所以執行緒的建立和銷毀的代價變得更小。

3.執行緒提高了效能,雖然執行緒巨集觀上是並行的,但微觀上卻是序列。從cpu角度執行緒並無法提公升效能,但如果某些執行緒涉及到等待資源(比如io,等待輸入)時,多執行緒允許程序中的其它執行緒繼續執行而不是整個程序被阻塞,因此提高了cpu的利用率,從這個角度會提公升效能。

4.在多cpu或多核的情況下,使用執行緒不僅僅在巨集觀上並行,在微觀上也是並行的。

這裡值得注意的是,上面的兩個執行緒如果改成兩個程序,那麼達不到所要的效果,因為程序有自己獨立的記憶體位址空間,而執行緒共享程序的記憶體位址空間。

另乙個看程序和執行緒的角度是程序模型基於兩類不同的概念:資源的組織和執行。在過去沒有執行緒的作業系統中,資源的組織和執行都是由程序完成的。但區分這兩者很多時候需要加以區分,這也是為什麼需要引入執行緒。

而執行緒,是每乙個程序中執行的乙個條線。執行緒雖然共享程序中的大多數資源,但執行緒也需要自己的一些資源,比如:用於標識下一條執行指令的程式計數器,一些容納區域性變數的暫存器,以及用於表示執行的歷史的棧。

總而言之:程序是組織資源的最小單位,而執行緒是安排cpu執行的最小單位。

其實在乙個程序中多個執行緒並行和在作業系統中多個程序並行非常類似,只是執行緒共享的是位址空間,而程序共享的是物理記憶體,印表機,鍵盤等資源……

每乙個程序和執行緒所獨自占有的資源如表1所示。

程序占有的資源

執行緒占有的資源

位址空間

全域性變數

開啟的檔案

子程序

訊號量

賬戶資訊

暫存器

狀態

程式計數器

表1.程序和執行緒所獨佔的資源

其中,執行緒可以共享程序獨佔的資源。

我們常用的術語「多執行緒」一般指的是在同乙個程序中多個執行緒的併發執行。如圖2所示。

圖2.沒有多執行緒的系統乙個程序只能由乙個執行緒

在多執行緒的程序中,每個執行緒輪流使用cpu,因此實際上執行緒並不是並行的,但從巨集觀上看,是並行的。

在多執行緒模型中,每乙個程序初始建立時只有乙個執行緒。這個執行緒可以通過呼叫系統的庫函式去建立其它執行緒。執行緒建立的執行緒並必須要為其指定位址,因為新的執行緒自動在建立它的位址空間內工作。雖然乙個執行緒可以建立另乙個執行緒,但通常來講,執行緒之間是並列的,並不存在層級關係。

當乙個程序完成其工作後,可以通過呼叫系統庫函式進行銷毀。

在作業系統中,執行緒可以實現在使用者模式下,也可以實現在核心模式下,也可以兩者結合實現。

執行緒實現在使用者空間下

當執行緒在使用者空間下實現時,作業系統對執行緒的存在一無所知,作業系統只能看到程序,而不能看到執行緒。所有的執行緒都是在使用者空間實現。在作業系統看來,每乙個程序只有乙個執行緒。過去的作業系統大部分是這種實現方式,這種方式的好處之一就是即使作業系統不支援執行緒,也可以通過庫函式來支援執行緒。

在這種模式下,每乙個程序中都維護著乙個執行緒表來追蹤本程序中的執行緒,這個表中包含表1中每個執行緒獨佔的資源,比如棧,暫存器,狀態等,如圖3所示。

圖3.在使用者空間中實現執行緒

這種模式當乙個執行緒完成了其工作或等待需要被阻塞時,其呼叫系統過程阻塞自身,然後將cpu交由其它執行緒。

這種的模式的好處,首先,是在使用者空間下進行程序切換的速度要遠快於在作業系統核心中實現。其次,在使用者空間下實現執行緒使得程式設計師可以實現自己的執行緒排程演算法。比如程序可以實現垃圾**器來**執行緒。還有,當執行緒數量過多時,由於在使用者空間維護執行緒表,不會占用大量的作業系統空間。

有好處就有壞處,這種模式最致命的缺點也是由於作業系統不知道執行緒的存在,因此當乙個程序中的某乙個執行緒進行系統呼叫時,比如缺頁中斷而導致執行緒阻塞,此時作業系統會阻塞整個程序,即使這個程序中其它執行緒還在工作。還有乙個問題是假如程序中乙個執行緒長時間不釋放cpu,因為使用者空間並沒有時鐘中斷機制,會導致此程序中的其它執行緒得不到cpu而持續等待。

執行緒實現在作業系統核心中

在這種模式下,作業系統知道執行緒的存在。此時執行緒表存在作業系統核心中,如圖4所示。

圖4.執行緒在作業系統核心中實現

在這種模式下,所有可能阻塞執行緒的呼叫都以系統呼叫(system call)的方式實現,相比在使用者空間下實現執行緒造成阻塞的執行時呼叫(system runtime call)成本會高出很多。當乙個執行緒阻塞時,作業系統可以選擇將cpu交給同一程序中的其它執行緒,或是其它程序中的執行緒,而在使用者空間下實現執行緒時,排程只能在本程序中執行,直到作業系統剝奪了當前程序的cpu。

因為在核心模式下實現程序的成本更高,乙個比較好的做法是另執行緒**利用,當乙個執行緒需要被銷毀時,僅僅是修改標記位,而不是直接銷毀其內容,當乙個新的執行緒需要被建立時,也同樣修改被「銷毀」的執行緒其標記位即可。

這種模式下同樣還是有一些弊端,比如接收系統訊號的單位是程序,而不是執行緒,那麼由程序中的哪乙個執行緒接收系統訊號呢?如果使用了表來記錄,那麼多個執行緒註冊則通過哪乙個執行緒處理系統訊號?

混合模式

還有一種實現方式是將上面兩種模式進行混合,使用者空間中程序管理自己的執行緒,作業系統核心中有一部分核心級別的執行緒,如圖5所示。

圖5.混合模式

在這種模式下,作業系統只能看到核心執行緒。使用者空間執行緒基於作業系統執行緒執行。因此,程式設計師可以決定使用多少使用者空間執行緒以及作業系統執行緒,這無疑具有更大的靈活性。而使用者空間執行緒的排程和前面所說的在使用者空間下執行實現執行緒是一樣的,同樣可以自定義實現。

作業系統 程序與執行緒

程序 作業系統結構的基礎,是乙個正在執行的程式 計算機中正在執行的程式例項 可以分配給處理器並由處理器執行的乙個實體 由單一順序的執行顯示,乙個當前狀態和一組相關的系統資源所描述的活動單元。程序切換 從正在執行的程序中收回處理器,然後再使待執行程序來占用處理器。這裡所說的從某個程序收回處理器,實質上...

作業系統 程序與執行緒

為什麼會有程序?以前的計算機效能較差,作業系統只支援單任務,也就是一次只能執行乙個任務,當這個任務執行完成之後,才能執行下乙個任務,例如msdos。當該任務進行io時,cpu會處於空閒狀態。隨著計算機效能增強,出現了多工作業系統,作業系統可以將多個任務同時載入到記憶體中,併發執行。當某個任務進行io...

作業系統 程序與執行緒

1 排程 在傳統的作業系統中,擁有資源的基本單位和獨立排程 分派的基本單位都是程序。而引入執行緒的作業系統,則把執行緒作為排程和分派的基本單位,而程序作為資源擁有的基本單位。2 併發性 在引入執行緒的作業系統中,程序之間可併發執行,在乙個程序中的多個執行緒亦可併發執行。3 擁有資源 程序都可以擁有資...