執行緒區域性儲存（，縮寫：TLS）是一種儲存持續期（storage duration），物件的儲存是線上程開始時分配，執行緒結束時回收，每個執行緒有該物件自己的例項。這種物件的連結性（linkage）可以是靜態的也可是外部的。 TLS 的一個例子是用全域性變量表示錯誤號。這可能在多執行緒併發時產生同步錯誤。執行緒區域性儲存的 errno 是個解決辦法。 Windows 的實現 每個程序都有一組標誌，共 TLS_MINIMUM_AVAILABLE 64 個。每個標誌可以被設為 FREE 或 INUSE，表示該 TLS 元素是否正在使用。注意這組標誌屬程序所有。當系統建立一個執行緒的時候，會為該執行緒分配與執行緒關聯的、屬於執行緒自己的 PVOID 型陣列（共有 TLS_MINIMUM_AVAILBALE 個元素），陣列中的每個 PVOID 可以儲存任意值。 Windows API 函式 TlsAlloc 用於獲取程序中一個未用的 TLS slot index。然後將該標誌從 FREE 改為 INUSE，並返回該標誌在位陣列中的索引，通常將該索引儲存在一個全域性變數中，因為這個值會在整個程序範圍內（而不是執行緒範圍內）使用。 呼叫 TlsSetValue dwTlsIndexpvTlsValue 將一個 PVOID 值放到執行緒的陣列中 dwTlsIndex 指定的具體位置。 函式 TlsGetValue 與 TlsSetValue 用於透過 TLS slot index 讀寫一個執行緒區域性儲存變數所指向的記憶體塊。函式 TlsFree 用於釋放 TLS slot index。 在的 FS0x2C 地址處，存放的是執行緒區域性儲存表的地址。每個執行緒用它自己的執行緒區域性儲存表的複製。TlsAlloc 返回表中一個未使用的索引。因此每個執行緒可以用 TlsSetValue index 設定執行緒區域性儲存值，用 TlsGetValue index 獲取執行緒區域性儲存值。 Windows 可執行程式也可以定義一個節（section），對映到程序每個執行緒的不同的記憶體分頁。這種節只定義在主程式裡，動態連結庫（DLL）不應該包含這種節因為不會被 LoadLibrary 函式在載入時初始化。 對於 Windows 系統來說，全域性變數或靜態變數會被放到 data 或 bss 段中，但當使用__declspec thread 定義一個執行緒私有變數的時候，編譯器會把這些變數放到 PE 檔案的 tls 段中。當系統啟動一個新的執行緒時，它會從程序的堆中分配一塊足夠大小的空間，然後把 tls 段中的內容複製到這塊空間中，於是每個執行緒都有自己獨立的一個 tls 副本。所以對於用__declspec thread 定義的同一個變數，它們在不同執行緒中的地址都是不一樣的。對於一個 TLS 變數來說，它有可能是一個 C 的全域性物件，那麼每個執行緒在啟動時不僅僅是複製 tls 的內容那麼簡單，還需要把這些 TLS 物件初始化，必須逐個地呼叫它們的全域性建構函式，而且當執行緒退出時，還要逐個地將它們析構，正如普通的全域性物件在程序啟動和退出時都要構造、析構一樣。Windows PE 檔案的結構中有個叫資料目錄的結構。它總共有 16 個元素，其中有一元素下標為 IMAGE_DIRECT_ENTRY_TLS，這個元素中儲存的地址和長度就是 TLS 表（IMAGE_TLS_DIRECTORY 結構）的地址和長度。TLS 表中儲存了所有 TLS 變數的建構函式和解構函式的地址，Windows 系統就是根據 TLS 表中的內容，在每次執行緒啟動或退出時對 TLS 變數進行構造和析構。TLS 表本身往往位於 PE 檔案的 rdata 段中。 Pthreads 的實現 Pthreads API 定義了執行緒特定的資料。 函式 pthread_key_create 與 pthread_key_delete 建立與刪除一個鍵，用於執行緒特定的資料。鍵的型別被稱為 pthread_key_t。鍵可以被所有執行緒看到。在每個執行緒，鍵可以用 pthread_setspecific 函式關聯到執行緒特定的資料。資料可以隨後用 pthread_getspecific 函式獲取。 特定於語言的實現 C and C C11 的關鍵字_Thread_local 用於定義執行緒區域性變數。在標頭檔案 threadsh 定義了 thread_local 為上述關鍵詞的同義。例如： include threadsh thread_local int foo 0 C11 引入了 thread_localSection 372 in C11 standard 關鍵字用於下述情形： 名稱空間 全域性 變數 檔案靜態變數 函式靜態變數 靜態成員變數 此外，不同編譯器提供了各自的方法宣告執行緒區域性變數： Solaris Studio CC IBM XL CCIBM XL CC Threadlocal storage GNU CGCC 331 ThreadLocal Storage ClangClang 20 release notes 與 Intel C Compiler Linux 平臺 Intel C Compiler 81 linux release notes Threadlocal Storage 使用語法： __thread int number Visual CVisual Studio 2003 Thread extended storageclass modifier Intel CC Windows systemsIntel C Compiler 100 Windows 平臺 Threadlocal storage CBuilder 與 Digital Mars C 使用語法： __declspec thread int number CBuilder 也可以使用語法： int __thread number Windows 的版本早於 Vista 與 Server 2008 __declspec thread 對於 DLL 只用於 DLL 被可執行程式繫結靜態載入，在 LoadLibrary 函式動態載入 DLL 將報告 protection fault 或 data corruption。 Java Java 語言中，執行緒區域性變數使用類物件表示。ThreadLocal 保持了變數的型別 T，可以透過 getset 方法訪問。例如，ThreadLocal 保持了 Integer 值： private static final ThreadLocalInteger myThreadLocalInteger new ThreadLocalInteger OracleOpenJDK 使用作業系統執行緒以避免效能代價。 NET 語言 C 與 Visual BasicNet NET Framework 語言，靜態域可標記 ThreadStatic attribute class FooBar ThreadStatic static int foo NET 40，SystemThreadingThreadLocalT 可用於分配與惰性裝入執行緒區域性變數。 class FooBar private static SystemThreadingThreadLocalint foo Also an API is available for dynamically allocating threadlocal variables Python Python 語言從版本 24 開始，threading 模組的 local 類可用於建立執行緒區域性儲存： import threading mydata threadinglocal mydatax 1 Ruby Ruby 語言能建立 訪問執行緒區域性變數使用 方法 Threadcurrent user_id 1 參考文獻 外部連結 ELF Handling For ThreadLocal Storage Document about an implementation in C or C ACE_TSSTYPE Class Template Reference RWTThreadLocalType Class Template Documentation Article Use threadlocal Storage to Pass Thread Specific Data by Doug Doedens ThreadLocal Storage by Lawrence Crowl Article Its Not Always Nice To Share by Walter Bright Practical ThreadLocal usage in Java httpswebarchiveorgweb20161220151503httpswwwcaptechconsultingcomblogsapersistencepatternusingthreadlocalandejbinterceptors GCC Category 執行緒