Chapter 2 Background
2.3 The Multi-threaded Evolution
如同第二章一開始的介紹,一個跑在多核心系統下的多執行緒程式需要作業系統 和使用者執行緒函式庫的支援。我們將在接下來的小節中詳細介紹關於作業系統 對於執行緒提供哪些支援,以及使用者執行緒函式庫的演進。
2.3.1 Thread Design in the Linux Kernel
執行緒是 CPU 排程的基本單元。一個行程並沒有限制可以擁有的執行緒數目,
但是,一支行程通常代表的就是一條執行緒。因此,由同一支行程創建的執行緒
另一方面,如果行程內擁有超過一條執行緒時,如 Figure 2.3 (b)所示,則這樣的 程式稱之為多執行緒應用程式。
在大部份傳統的作業系統,執行緒可以被分為兩大類,分別是使用者執行緒 (user thread)和核心執行緒 (kernel thread)。使用者執行緒只在 user-level 的程式 中運作,它主要是透過使用者執行緒函式庫創建。另一方面,核心執行緒只存 在 kernel-level。
在早期的 Linux 作業系統中,一支多執行緒的應用程式,無論是被創造、處 理、排程都是透過使用者執行緒函式庫完成。多執行緒的應用程式裡的每條執行 緒在核心中都只對應到一份行程描述器結構。因此,只要有一條執行緒正在存取 Linux 核心資源時,其它的執行緒將被暫停。
Figure 2.3 Threads Architecture
核心執行緒作用上與行程相似,因此,許多行程的特性,核心執行緒也具備。
執心執行緒不同於使用者執行緒,它可以獨立的被核心排程。在 Linux 2.6 核心 系統釋出之前,因為較舊的核心並沒有核心執行緒的設計,所以,過去行程與核 心執行緒代表的是相同層面的結構,也就是說核心執行緒指的就是行程。從 Linux 2.6 核心開始,所有新的核心都已經有支援核心執行緒,它在 Linux 2.6 後的核心 系統裡又被稱為輕量級行程 (LWP)。
Figure 2.4 Light-weight Process Architecture
輕量級行程的架構,如 Figure 2.4 所示。每一個輕量級行程,都有一塊獨立 的行程描述器空間,但是輕量級行程與它的父行程仍共用相同的核心資源。這樣 的設計使的當某個輕量級行程對核心資源產生改變時,與其共用的核心執行緒將 立即反應。
一個最簡單的多執行緒應用程式的設計,讓每一支使用者執行緒都關聯到一 個輕量級行程。由於一個輕量級的行程可被核心獨立排程,因此,每一條使用者 執行緒在核心中都可被視為獨立的個體。
目前的 Linux 作業系統已經支援 SMP 架構,並且整合新的架構到 Linux 2.6 的核心。如果有 N 顆 CPU,SMP 架構可以為每一顆 CPU 排定一個輕量級行程。
Figure 2.5 Nx1 Multi-Thread Model in LinuxThread Library
2.3.2 Thread Design in the User-level
在此小節中,我們將從最早開始的 LinuxThread,到目前比較廣泛使用的 NGPT 和 NPTL 使用者執行緒函式庫提出它們彼此的優缺點,及演進的過程。
The LinuxThread Library
LinuxThread Library 是最早被發展用來支援多執行緒應用程式的使用者執行緒函 式庫。如 Figure 2.6 所示,它是以 Nx1 的模型做為多執行緒應用程式的架構。Nx1 模型代表的是所有的使用者執行緒在核心中都只對應一支行程。然而,這種作法 並無法發揮多執緒應用程式的好處。因為,當某一條執行緒正在存取核心資源時,
其它執行緒必需等待。
為了改進 LinuxThread Library 的缺點,兩個重新修改 LinuxThread Library 的 計畫被提出,分別是 NGPT 和 NPTL。由於新的使用者執行緒函式庫開發已日漸 成熟,所以對於 LinuxThread 的維護現在已經被中止。
The NGPT Library
發展 NGPT (Next Generation POSIX Thread)的團隊來自 IBM 的一群工程師。在[8]
中有提到,NGPT 在效能上並不及 NPTL 突出,所以 NGPT 在 2003 年就已經被 放棄繼續發展,取而代之的是 NPTL。目前有關多執行緒應用程式的開發,所使 用的函式庫都已改為 NPTL。在 Linux 作業系統裡,NPTL 已經成為
POSIX-compliant library 的標準,而且它已經被整合進 GNU C library 裡。
The NPTL Library
NPTL (Native POSIX Thread Library )是 Red Hat 發展的一套使用者執行緒函式庫。
它使用與 LinuxThread 函式庫相似的方法,藉由系統呼叫「clone」去完成多執行 緒應用程式的實作。不同的是,NPTL 使用「clone」系統呼叫創建的是輕行程 (lightweight process),而非一般的行程。NPTL 並非完全是 user-level 的函式庫,
它需要核心支援,使得每一支在多執行緒應用程式內的使用者執行緒都可以獨立 排程。
User Thread 1 User Thread 2 User Thread 3 User Thread N
NTPL
Linux Kernel API
Lightweight
Figure 2.6 1x1 Multi-Thread Model in NPTL Library
NPTL 函式庫提供兩類不同的多執行緒應用程式的實作模型。第一類模型對 每一條使用者執行緒在核心中都提供一支輕行程對應,如 Figure. 2.6 所示,這類 模型被稱為 1x1 架構。使用 1x1 架構的多執行緒應用程式,在核心中都可以獨立 被排程,所以,每條執行緒都可以同時存取核心資源。
Figure 2.7 MxN Multi-Thread Model in NPTL Library
另外一類實作模型是 MxN 架構,如 Figure. 2.7 所示。它是將 M 條使用者執 行緒對應到 N 支輕行程,所以,在此架構下的執行緒排程只在 user-level 實作。
由於 MxN 的架構使得執行緒間的切換行為必需經由函式庫完成,造成使用 MxN 架構開發多執行緒應用程式的複雜度大大提高,因此,現今無論是哪一種 Linux 平台,關於多執行緒程式的實作都已經採用 1x1 架構。