1. 程式人生 > >執行緒詳細剖析(一)

執行緒詳細剖析(一)

摘自《C++多核高階程式設計》

6.1 什麼時執行緒

執行緒時程序中可執行程式碼流的序列,它被作業系統排程,並在處理器或核心上執行。所有的程序都有一個主執行緒(primary thread)。主執行緒時程序的控制流或執行線路。具有多個執行緒的程序擁有和執行緒數目一樣多的控制流。每個執行緒獨立併發的執行自身的指令序列。具有多個執行緒的程序時多執行緒的。執行緒分為使用者級執行緒核心級執行緒。與程序相比,核心級執行緒在建立、維護和管理方面給作業系統帶來的負擔都要輕的多,因為與執行緒關聯的資訊很少。核心執行緒被稱作輕量級程序,因為它的開銷要比程序少。

執行緒執行程式中無關的併發任務。執行緒可用於簡化具有固有併發的應用程式的程式結構,其方式與通過函式或過程來封裝功能性使得應用程式的結構更簡單相同。執行緒可以封裝併發功能。執行緒在一個程序的地址空間中使用最少的共享資源,相比之下,應用程式則使用多個程序。這使得作業系統得到總體更加簡單的程式結構。如果正確使用,執行緒可以通過利用多核處理器併發來改進應用程式的吞吐率和效能。每個執行緒負責被分配的一個子任務,然後執行緒獨立管理子任務的執行。可以為每個執行緒指定反映它執行的子任務的重要性的優先順序。

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

執行緒有三種實現模型:

1)使用者級或應用程式級執行緒

2)核心級執行緒

3)使用者級和核心級混合執行緒

圖6-1顯示了3種執行緒實現模型。圖6-1(a)顯示了使用者級執行緒,(b)顯示了核心級執行緒,(C)顯示了使用者級執行緒和核心級執行緒的混合。

 這些實現之間較大的區別之一就是它們的模式以及要指派給處理器的執行緒的能力。這些執行緒執行在使用者模式下或核心模式下。

1)在使用者模式下,程序或執行緒時執行程式或連結庫中的執行,它們不對作業系統核心進行任何呼叫。

2)在核心模式下,程序或執行緒時進行系統呼叫,例如訪問資源或丟擲異常。同時,在核心模式下,程序或執行緒可以訪問在核心空間中定義的物件。

使用者級執行緒駐留在使用者空間或模式。執行時庫管理這些執行緒,它也位於使用者空間。它們對於作業系統是不可見的,因此無法被排程到處理器核心。每個執行緒並不具有自身的執行緒上下文。因此,就執行緒的同時執行而言,任意給定時刻每個程序並不具有一個執行緒在執行,而且只有一個處理器核心會被分配給該程序。對於一個程序,可能有成千上萬個使用者級執行緒,但是它們對系統資源沒有影響。執行時庫排程並分派這些執行緒。如同在圖6-1(a)中看到的那樣,庫排程器從程序的多個執行緒中選擇一個執行緒,然後該執行緒和該程序執行的一個核心執行緒關聯起來。核心執行緒將被作業系統排程器指派到處理器核心。使用者級執行緒時一種“多對一”的執行緒對映。

核心級執行緒駐留在核心空間,它們是核心物件。有了核心執行緒,每個使用者執行緒被對映或繫結到一個核心執行緒。使用者執行緒在其生命期內都會繫結到該核心執行緒。一旦使用者執行緒終止,兩個執行緒豆漿離開系統。這被稱作“一對一”執行緒對映,如圖6-1(b)所示。作業系統排程器管理、排程並分派這些執行緒。執行時庫為每個使用者級執行緒請求一個核心級執行緒。作業系統的記憶體管理和排程子系統必須要考慮到數量巨大的使用者級執行緒。您必須瞭解每個程序允許的執行緒的最大數目是多少。作業系統為每個執行緒建立上下文。執行緒的上下文將在本章稍後部分介紹。程序的每個執行緒在資源可用時都可以被分派到處理器核心。

混合執行緒實現時使用者執行緒和核心執行緒的交叉,使得庫和作業系統都可以管理執行緒。使用者執行緒由執行時庫排程器管理,核心執行緒有作業系統排程器管理。在這種實現中,程序有著自己核心執行緒池。可執行的使用者執行緒由執行時庫分派並標記為準備號執行的可用執行緒。作業系統選擇使用者執行緒並將它對映到執行緒池中的可用核心執行緒。多個使用者執行緒可以分配給相同的核心執行緒。在圖6-1(c)中,程序A在它的執行緒池中有兩個核心執行緒,而程序B有3個核心執行緒。程序A的使用者執行緒2和3被對映到核心執行緒(2),程序B有5個執行緒,使用者執行緒1和2對映到同一個核心執行緒(3),使用者執行緒4好5對映到核心同一個核心執行緒(5)。當建立新的使用者執行緒時,只需要簡單的將它對映到執行緒池中現有的一個核心執行緒即可。