1. 程式人生 > >作業系統概念-個人筆記(執行緒)

作業系統概念-個人筆記(執行緒)

作業系統第六版-第五章-執行緒

執行緒

執行緒,有時也被稱為輕量級程序(LWP),是一個基本的 CPU 執行單元;它包含了一個執行緒 ID、一個程式計數器、一個暫存器組和一個堆疊。它與屬於同一個程序的其它的執行緒共享程式碼段、資料段,以及其它的作業系統資源(比如:開啟的檔案和訊號)。一個傳統的(或者說重量級)程序有一個單獨的控制執行序列。如果一個程序有多個控制執行序列,那麼它就能夠同時進行多個任務。

執行緒的優點

1. 提高了響應速度:多執行緒互動式應用程式可以允許程式在它的一部分被阻塞或正在執行一個冗長的操作時持續執行,從而提高了了對使用者的響應速度。例如,一個多執行緒網頁瀏覽器可以在一個執行緒下載圖片時利用另外一個執行緒與使用者互動。

2. 資源共享:預設情況下,執行緒共享它們所屬程序的儲存器和資源。程式碼共享的優點在於它允許應用程式在同樣的地址空間內擁有多個不同的活動執行緒。

3. 經濟實惠:為程序建立分配儲存器和資源代價高昂。因為執行緒共享它們所屬程序的資源,所以執行緒的建立和上下文轉換更為划算。建立和維護程序與建立和維護執行緒的開銷孰大孰小難以測量(一般根據經驗判斷),但是通常建立和管理程序比建立和管理執行緒需要更多的時間。

4. 提高了多處理機體系結構的利用率:在多處理機體系結構中,多執行緒的優點就更加顯著了。在這種系統中,多個執行緒可以在不同的處理器上並行執行。一個單執行緒程序只能夠在一個 CPU 上執行,而不論有多少 CPU 可供使用。在多 CPU 機器中,多執行緒提高了併發性。在單處理機體系結構中,CPU 通常快速的在每個執行緒之間移動,如此以至於使用者感覺到這是在並行執行(這是個假象),但是實際上同時只有一個執行緒在執行。

使用者執行緒和核心執行緒

對使用者執行緒的支援通常處於核心之上,執行緒庫提供了對執行緒的建立、排程和管理的支援,這無需來自核心的支援。因為核心並不知道使用者級執行緒的存在,所有的執行緒建立和排程工作都在使用者空間完成,而且整個過程不受核心的干涉。所以,使用者級執行緒的建立和管理通常很快;然而,它們也有一些缺點。例如:如果核心是單執行緒的,那麼任何使用者級執行緒執行一個導致阻塞的系統呼叫時就會導致整個程序阻塞,即使程式內部的其它執行緒可以執行。

核心執行緒由作業系統直接支援:核心在核心空間內實現了執行緒的建立、排程和管理。因為執行緒管理由作業系統完成,所以核心執行緒的建立和管理要比使用者執行緒慢。然而,由於執行緒由核心管理,如果一個執行緒執行一個導致阻塞的系統呼叫,那麼核心可以排程程式中的其它執行緒執行。同樣,在多處理機環境中,核心能夠在不同的處理器中排程執行緒。大多數現代作業系統都支援核心執行緒。

多對一模型

多對一模型(many-to-one model)將多個使用者級執行緒對映到一個核心執行緒。執行緒管理在使用者空間完成,所以它的效率比較高。但是如果一個執行緒呼叫了導致阻塞的系統呼叫的話,那麼將阻塞整個程序。而且,因為一次只有一個執行緒可以訪問核心,所以在多處理機環境中多個執行緒不能夠併發執行。

一對一模型

一對一模型(one-to-one model)將每個使用者執行緒對映到一個核心執行緒。它允許在一個執行緒呼叫導致阻塞的系統呼叫的情況下持續執行其它的執行緒,從而提供了比多對一模型更好的併發性;它也允許多個執行緒在多處理機環境中並行執行。這種模型的唯一缺點在於建立一個使用者執行緒就需要建立一個相應的核心執行緒。因為建立核心執行緒的開銷會加重應用程式的負擔,所以這種模型的大多數實現都要限制系統支援的執行緒數量。

多對多模型

多對多模型(many-to-many model )將使用者級執行緒多路複用到與之數量相等或少一點的核心執行緒。核心執行緒的數量由具體的應用程式或具體的機器確定(分配給應用程式的核心執行緒數量在多處理機環境中可能比單處理機環境中多)。然而,多對一模型允許開發者隨心所欲的建立使用者執行緒。但是,因為核心一次只能排程一個執行緒,所以並不能獲得真正的並行性。一對一模型允許更大的並行性,但是開發者必須小心,以免在一個程式中建立過多的執行緒(而且在某些情況下可能會限制開發者能夠建立的執行緒的數目)。多對多模型則免卻了所有這些缺點:開發者能夠建立所需的使用者執行緒,而且相應的核心執行緒能夠在多處理機環境中並行執行。而且當一個執行緒執行導致阻塞的系統呼叫時,核心能夠排程其它的執行緒執行。(golang的協程模型就是多對多

執行緒池

假設不論伺服器何時接收到一個請求,它都會建立一個獨立的執行緒來處理這個請求。而建立一個獨立的執行緒明顯要優於建立一個獨立的程序,雖然如此,多執行緒伺服器依然面臨一些潛在的問題。第一個問題是在處理請求之前建立執行緒的時間需求,還要考慮到該執行緒一旦完成工作就要被丟棄。第二個問題就更加嚴重了:如果我們允許為每一個請求都建立一個新執行緒來處理,那麼我們難以在系統中實現足夠數量的執行緒。不受限制的建立執行緒可能耗盡系統資源,比如:CPU 時間或儲存器。

一種解決方案是執行緒池。執行緒池的思想是在程序開始時建立一定數量的執行緒並將它們置入一個池(pool)中,執行緒在這個池中等待工作。當伺服器接收到一個請求時,它就從池中喚醒一個執行緒(如果有可用的執行緒),由它來處理請求。一旦執行緒服務完畢,它就返回執行緒池等待後面的工作。如果池中沒有可用的執行緒,那麼伺服器就等待,直到某個執行緒被釋放。

執行緒池有如下優點:

1.  利用已存在的執行緒服務請求要比等待建立一個執行緒要快。

2.  執行緒池限制了執行緒的數量。在不能夠支援大量的併發執行緒的系統中這一點特別重要。

執行緒池中的執行緒數量的設定要根據一些因素,比如:系統中的 CPU 數量、實體記憶體的容量和所期望的併發的客戶端請求的數量。更加完善的執行緒池體系結構能夠根據應用情況動態調節執行緒池中的執行緒數量。這樣的體系結構優點更多,系統負載較低時擁有一個較小的執行緒池,因此所需的儲存器更少。