操作系統精髓與設計原理學習筆記四:線程

一、進程和線程:

這裏所說的進程個概念要比前面給出的更復雜和精細。實際上,它包含兩個獨立的概念:一個與資源管理權有關(進程),一個與執行相關(線程)

資源所有權:一個進程包括一個存放進程映像的虛擬地址空間;進程映像是程序、數據、棧和進程控制塊中定義的屬性的集合。一個進程總是擁有對資源的控制或所有權,這些資源包括內存,IO通道,IO設備和文件等。操作系統提供保護功能。以防止進程之間發生不必要的與資源相關的衝突。

調度執行:一個進程沿着 可以通過一個或多個程序的路徑 執行,其執行過程可能與其他進程的執行過程交替進行。因此,一個進程具有一個執行狀態(運行就緒等)和一個被分配的優先級,它是一個可被操作系統調度和分派的實體。

爲了區分以上兩點,分派的單位通常稱爲線程輕量級進程,而擁有資源所有權的單位通常稱爲進程任務

1,、多線程:

多線程是指操作系統在當進程內支持多個併發執行路徑的能力。(Java運行時環境是單進程多線程的一個例子)。

在多線程環境中,進程被定義成資源分配的單位和一個被保護的單位,與進程相關聯的有:存放進程映像的虛擬地址空間;受保護的對處理器,其他進程,文件和IO資源的訪問。

在一個進程中,可能有一個或多個線程,每個線程有:線程執行狀態(運行、就緒等);在未運行時保存的線程上下文;一個執行棧;用於每個線程局部變量的靜態存儲空間,與進程內其他線程共享的對進程的內存和資源的訪問。

單線程單進程模型中(沒有明確的線程概念):進程的表示包括它的進程控制塊用戶地址空間,以及在進程執行中管理調用/返回行爲的用戶棧內核棧。當進程正在運行時,處理器寄存器將被該進程控制;當進程不運行時,這些處理器寄存器中的內容將被保存。

多線程環境中:進程仍然只有一個與之關聯的進程控制塊用戶地址空間。但是每個線程都有一個獨立的棧,還有獨立的線程控制塊(用於包含寄存器值、優先級和其他與線程相關的狀態信息)。

進程中的所有線程共享該進程的狀態和資源,他們駐留在同一塊地址空間中,並且可以訪問到相同的數據。當一個線程改變了內存中的一個數據項時,其他線程在訪問這一數據項時能夠看到變化後的結果。

線程的優點:

在一個已有進程正創建一個新線程比創建一個全新進程所需的時間要少許多;

終止一個線程比終止一個進程花費的時間少;

同一進程內線程間切換比進程間切換花費的時間少;

線程提高了不同的執行程序間通信的效率。獨立進程間的通信需要內核的介入,以提供保護和通信所需要的機制;但是,由於在同一個進程中的線程共享內存和文件,他們無需調用內核就可以相互通信。

因此,如果一個應用程序或函數被實現爲一組相關聯的執行單位,那麼用一組線程比用一組分離的進程更有效。

在支持線程的操作系統中,調度和分派時在線程基礎上完成的,因此大多數與執行相關的信息可以保存在線程級的數據結構中。但是,有些活動影響着進程中的所有線程,操作系統必須在進程一級對他們進行管理。

2、線程功能特性

和進程一樣,線程具有執行狀態,且可以互相之間進行同步。

線程的關鍵狀態有運行態、就緒態和阻塞態。一般來說,掛起態對線程沒有什麼意義(該狀態是一個進程級的概念)。特別地,如果一個進程被換出,由於它的所有線程都共享該進程的地址空間,因此他們必須都被換出。

如果一個程序在單處理器上運行,那麼必須順序的產生請求並且順序的處理結果,但是對兩個應答的等待時併發的。在單處理器中,多道程序設計使得在多個進程中的多個線程可以交替執行。

線程同步:一個進程中的所有線程共享同一個地址空間和注入打開的文件之類的其他資源。一個線程對資源的任何修改都會影響同一個進程中其他線程的環境。因此,需要同步各種線程活動,以便他們互不干涉且不破壞數據結構。

二、線程分類

線程的實現可以分爲兩大類:用戶級線程內核級線程

1)用戶級線程。

在一個純粹的用戶級線程軟件中,有關線程管理的所有工作都由應用程序完成,內核意識不到線程的存在。

任何應用程序都可以通過使用線程庫被設計成多線程程序。線程庫是用於用戶級線程管理的一個例程包,它包含用於創建和銷燬線程的代碼、在線程間傳遞消息和數據的代碼、調度線程執行的代碼、以及保存和恢復線程上下文的代碼。

在默認情況下,應用程序從單線程開始,並在該線程中開始運行。該應用程序及其線程被分配給一個由內核管理的進程。在應用程序正在運行(進程處於運行態)的任何時刻,應用程序都可以派生一個在相同進程中運行的新線程(派生線程是通過調用線程庫中的派生例程完成的,通過過程調用,控制權唄傳遞給派生例程)。線程庫爲新線程創建一個數據結構,然後使用某種調度算法,把控制權傳遞給該進程中處於就緒態的一個線程。

在前一段描述的所有活動都發生在用戶空間中,並且發生在一個進程內,而內核並不知道這些活動。內核繼續以進程爲單位進行調度,並且給該進程指定一個執行狀態。

優點(相對於內核線程):

由於所有線程管理數據結構都在一個進程的用戶地址空間中,線程切換不需要內核態特權;

調度可以使應用程序相關的,可以做到爲應用程序量身定做調度算法而不擾亂底層的操作系統調度程序;

用戶級線程可以再任何操作系統中運行,線程庫是一組供所有應用程序共享的應用程序級別的函數。

缺點(相對於內核線程):

當用戶級線程執行一個會引起阻塞的系統調用時,不僅這個線程會被阻塞,進程中的所有線程都會被阻塞。

在純粹的用戶級線程策略中,多線程應用程序不能利用多處理技術,內核一次只把一個進程分配給一個處理器,因此一次進程中只有一個線程可以執行。

2)內核級線程。

在一個純粹的內核級線程軟件中,有關線程管理的所有工作都是由內核完成的,應用程序部分沒有進行線程管理的代碼,只有一個到內核線程設施的應用程序編程接口。

內核爲進程及其內部的每個線程維護上下文信息。調度是由內核基於線程完成的。優勢:首先,內核可以同時把同一個進程中的多個線程調度到多個處理器中;再者,如果進程中的一個線程被阻塞,內核可以調度同一個進程中的另一個線程;另外,內核例程自身也是可以使用多線程的。缺點:把控制從一個線程傳送到同一個進程內的另一個線程時,需要到內核的狀態轉換。

3)混合方法。

在混合系統中,線程創建完全在用戶空間中完成,線程的調度和同步也在應用程序中進行。一個應用程序中的多個用戶級線程被映射到一些(小於或等於用戶級線程的數目)內核級線程上。

在混合方法中,同一個應用程序中的多個線程可以在多個處理器上並行地運行,某個會引起阻塞的系統調用不會阻塞整個進程。如果設計正確,該方法將會結合純粹內核級線程和用戶級線程的優點。

Java應用程序:Java從根本上支持線程的概念。不僅Java語言本身能夠很方便地支持多線程應用程序開發,Java虛擬機也是一個多線程進程,它爲Java應用程序提供調度機制和內存管理。


四、Windows7線程

Windows使用兩類與進程相關的對象;進程和線程。進程是對應一個擁有內存、打開的文件等資源的用戶作業或應用程序的實體;線程是順序執行的一個科分派的工作單元,並且它是可中斷的,因此,處理器可以切換到另一個線程。

一個Windows進程必須至少包含一個執行線程,該線程可能會創建別的線程。在多處理器系統中,同一個進程的多個線程可以並行的執行。

由於不同進程中的線程可能並非執行,因而Windows支持進程間的併發性。此外,同一個進程中的多個線程可以分配給不同的處理器並且同時執行。一個含有多線程的進程在實現併發時,不需要使用多進程的開銷。同一個進程中的線程可以通過他們的公共地址空間交換信息,並訪問進程中的共享資源,不同進程中的線程可以通過在兩個進程間建立的共享內存交換信息。


五、Linux的進程和線程管理

Linux中的進程或任務由一個task_struct數據結構表示。

傳統的UNIX系統支持美國之行的進程中只有一個單獨的一個線程,但現代典型的UNIX系統支持一個進程中含有多個 內核級線程。

Linux提供一種不區分進程和線程的解決方案。用戶級線程被映射到內核級進程上,組成一個用戶級進程的多個用戶級線程被映射到共享同一個組ID的多個Linux內核級進程上。這使得這些進程可以共享文件和內存等資源,使得同一組中的進程調度切換時不需要切換上下文。

當兩個進程共享相同的虛存時,它們可以被當做是一個進程中的線程。

當Linux內核執行從一個進程到另一個進程的切換時,它將堅持當前進程的頁目錄地址是否和將被調度的進程相同。如果相同,那麼它們共享同一個地址空間,所以此時上下文切換僅僅是從代碼的一處跳轉到代碼的另一處。

雖然屬於同一進程組的被克隆的進程共享同一內存空間,但它們不能共享同一個用戶棧。


六、總結:

某些操作系統區分進程和線程的概念,前者涉及資源的所有權,後者涉及程序的執行,這種方法可以使性能提高、編碼方便。在多線程系統中,可以再一個進程內定義多個併發線程。這可以通過使用用戶級線程或內核級線程來完成。

用戶級線程對操作系統是未知的,他們由一個正在進程的用戶空間中運行的線程庫創建並管理。用戶線程是非常高效的,因爲從一個線程切換到另一個線程不需要進行狀態切換,但是,一個進程中一次只有一個用戶級線程可以執行,如果一個線程發生阻塞,整個進程都會被阻塞。

進程內包含的內核級線程是由內核維護的。由於內核認識他們,因而同一個進程中的多個線程可以再多個處理器上並行執行,一個線程的阻塞不會阻塞整個進程,但當從一個線程切換到另一個線程時就會需要進行模式切換。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章