1. 程式人生 > >程序與執行緒(三)——執行緒的概念與實現

程序與執行緒(三)——執行緒的概念與實現

一 什麼是執行緒? 程序中的一條執行流程。 有了執行緒,程序發生了一系列的變化。首先是(1)資源管理,包括地址空間(程式碼段,資料段):程序就是由來管理資源的:地址空間,開啟的檔案,訪問的網路。(2)執行緒把程序的另一部分功能給拆出來了。 程序的執行功能,程序的執行狀態交給了執行緒來管理。在執行的角度上來看,程式碼在執行的平臺的執行流程,我們把它理解為一個執行緒,執行緒稱成為了程序的重要組成部分。 程序主要完成資源的管理之外,需要有一系列的執行緒來完成執行的過程。程序裡面存在多個執行緒,執行緒是共享程序提供的資源平臺,屬於同一個程序的執行緒共享程序所擁有的資源,可以直接訪問程序的提供程式碼資料記憶體和檔案等,執行緒之間的資源共享很容易實現了。

二 執行緒的組織結構: 1.執行緒控制塊TCB TCB和程序一樣,執行緒具有自己的TCB執行緒控制塊。但是和PCB有區別,TCB只負責管理執行流程相關的一系列的資訊,包含執行的程式計數器PC,SP堆疊,暫存器。因為有不同的執行流,不同的控制流,需要通過暫存器來表示執行狀態,這個是每一個執行緒所獨立的資訊。但是它的記憶體空間,比如說它的堆空間,它的程式碼段,它的資料段是所有執行緒所共享的。所以執行緒有各自獨立的部分,有共享的部分。這是執行緒的特點。 缺點:因為可以共享,如果有一個執行緒寫錯了,它就有可能破壞其他的執行緒間的所共享的資源。一個執行緒把資料破壞了,其他執行緒也需要資料,其他執行緒也會導致崩潰的現象。安全可靠性沒有辦法保障。
這時候出現了適用性的問題 (1)高效能運算,使用執行緒 (2)Internet的服務,早期瀏覽器使用執行緒來實現。 現在CPU計算不是瓶頸,安全性要得到保障。chrome每一個網頁用程序實現。
2. 執行緒=程序-共享資源 
單程序在執行的時候就只有一個控制流。多執行緒時,在程序空間裡面會出現多個控制流,而且每個控制流的流程是不一樣的:所以 執行緒需要獨立的暫存器,堆疊,能夠共享程式碼段,資料段,檔案,網路資源等等 。如下圖所示:現在有兩類資源,一種是共享的,一種是獨佔的。 獨佔的資源和它的控制執行相關的,需要把這部分資訊單獨的保護起來,避免執行緒之間的狀態的破壞。如果兩個執行緒共享一個PC(程式計數器),那執行流程就不可能實現分別執行不同的流程。


瞭解: Context————上下文 程序共享CPU,停止當前程序,並排程其他程序的切換叫做上下文切換。  切換要用到的暫存器,暫存器是和我們緊密相連的。PC,棧指標暫存器,在切換時要儲存到PCB。恢復時又重新取出來,重新賦值,使得接下來CPU繼續執行。 上下文切換的開銷越小越好,且所有資訊都與硬體緊密相連,所以OS中實現是用匯編程式碼。
三 執行緒和程序的比較(重要)
1.程序是資源的分配單位(記憶體,開啟的檔案,網路等),執行緒是CPU排程單位,CPU是一種特殊的資源,主要強調的是控制流所必要的相關的資訊。 2.程序是一個完整的資源平臺,而執行緒是獨立了必不可少的資源,這個資源包含暫存器和堆疊。 3.執行緒同樣具有就緒、執行、阻塞狀態。 和程序的狀態是一樣的。在這裡我們把程序的功能做了切分。把這部分的功能給了執行緒。 4.執行緒可以實現併發執行的時間和空間的開銷。 比如: (1)執行緒的建立施加比程序要短——因為程序在建立過程中,還需要去建立其他一些管理的資訊,比如記憶體管理,開啟的檔案管理。而執行緒在建立的時候,直接重用程序管理好的資源,所以,建立時間會短。 (2)同理,執行緒的銷燬時間也要短——因為它不需要考慮資源的釋放問題。 (3)另一方面,在做切換的時候呢,在同一程序中的執行緒切換也會很快。因為執行緒具有同一個地址空間, 屬於同一程序的執行緒,擁有同一頁表。在切換的時候,不需要切換記憶體管理所需要的頁表。而對於程序而言,我們要切換程序的話, 需要把頁表也要切換掉 ,而切換頁表的開銷是比較大的。因為涉及到要訪問的地址空間是不一樣的,很多cache資訊,TLB的資訊,硬體的資訊都會無效,需要重新載入,開銷較大。但是,執行緒切換的時候,共享同一頁表,所有的資訊可以重用,不需要有缺失,不需要做失效處理,效率會很高。 (4)另一方面,同一程序中的執行緒,它共享了程序包含的資源,在做執行緒之間的資料傳遞的時候,就不需要通過核心了,直接通過記憶體地址可以訪問到,使得執行緒之間的資料交換的效率會很高。 綜上所示,執行緒在執行過程中,它的時間效率,空間效率比程序高。

四 執行緒的實現方式

1.核心支援執行緒KST(Kernel Supported Threads)

核心執行緒切換比較快,切換開銷小。

核心支援執行緒,對使用者的執行緒而言,只要完成一次執行緒切換,需要從使用者態到核心態的變換,開銷相對於前面的使用者管理開銷會大一些


2.使用者級執行緒ULT(User Level Threads)

使用者執行緒:使用者態的庫完成了對執行緒控制的管理,它的執行緒控制塊在庫裡面實現的。對OS而言,它看不到TCB,它只能看到我們的程序——整個程序的資訊作業系統可以看到,但是程序裡面的執行緒資訊由我們的執行緒管理庫來實現的,執行緒資訊作業系統看不到。所以說整個執行緒的排程和管理, 作業系統不直接參與,而是由我們的執行緒庫來完成。 作業系統感知不到執行緒,只能感知程序,只能把程序阻塞,那麼所以屬於程序的執行緒也會被跟著阻塞。 使用者態的執行緒庫沒有辦法打斷當前使用者的執行緒的執行,它沒有這個特權,但是作業系統有——作業系統會管理中斷,一旦會產生中斷之後, CPU的控制權就落在了作業系統手裡了,就可以對中斷進行進行一步的處理,特別是時鐘中斷——可以來完成強制的切換把執行緒停止,給其他的執行緒執行。但是我們的執行緒庫,使用者態沒有這個能力,如果使用者執行緒不主動放棄CPU的使用權,其他執行緒也無法執行,這是使用者執行緒的缺點。
3.組合方式: 輕量級程序

LWP作為一個介面來使用,LWP可以把使用者執行緒和核心執行緒連線起來。核心看不到使用者程序,但是使用者程序可以通過LWP訪問核心。


使用者執行緒與核心執行緒間,可以是多對一,一對一,多對多

多對一:

一對一:
多對多: