スレッド局所記憶

スレッド局所記憶（, TLS）は、もしくは大域的なメモリをスレッドごとに局所的に使用するためのコンピュータプログラミングの方法である。
プロセス内のスレッドはすべてアドレス空間を共有しており、同じプロセスのスレッドから参照する際、静的変数やグローバル変数は同じメモリ番地に配置される。
一方スタック上の変数はすべてのスレッドが自分のスタックを持つためスレッドに対して局所的であり、異なるメモリ番地に存在する。
同じ静的変数・グローバル変数を参照する二つのスレッドが（変数をスレッドに対して局所的にすることで）実際には異なるメモリ番地を参照できることが望ましい場合がある。たとえば典型的な例としてC言語のエラーコードを格納する変数 codice_1 がある。
少なくともメモリアドレスを格納できるサイズの変数をスレッドに対して局所的にすることが可能なら、メモリブロックを確保し、そのメモリアドレスをスレッドローカルな変数に格納すれば、原理的には任意のサイズのメモリブロックをスレッド局所にすることが可能である。
プラットフォーム固有実装.
マルチスレッドをサポートするプラットフォームや規格には、通例TLSを利用するためのAPIが用意されている。
Windowsでの実装.
Microsoft Windowsでは、Windows APIの関数 codice_2 を用いると、未使用のTLSスロット番号を取得できる。これによりその番号は使用中となる。
次にcodice_3およびcodice_4関数を用いて、番号によって識別されるスレッドローカルな変数に対する読み書きができる。codice_4 は現在のスレッド（関数を呼び出したスレッド）の変数にしか影響を与えない。
codice_6 関数を用いると、TLSスロット番号を解放することができる。番号は再び未使用となり、あらたな codice_2 により再度使用することが可能となる。
Pthreadsでの実装.
POSIXスレッド (Pthreads) ではスレッド固有データ () と呼ばれる。このスレッド固有データは、WindowsにおけるTLSの関数や機能と同様である。codice_8 で "key" を生成し、この "key" はcodice_9によって任意のデータと関連付けることができる。各 "key" に関連付けられたデータは codice_10 を用いて取得することができる。codice_8はオプションで任意の "destructor" 関数を与えることも可能であり、スレッド固有データが NULL でなければ、スレッドが終了する際 "destructor" が呼ばれる。また、"key" は codice_12 で破棄しなければならない。
プログラミング言語固有の実装.
プログラマが適切な API 関数を呼ぶのではなく、プログラミング言語自体が TLS をサポートするよう拡張することもできる。
C/C++.
C言語では C11 からキーワード codice_13 を用いて TLS を使用できる。
C++ では C++11 においてスレッドに関する規定とキーワード codice_14 が導入された。以下のケース全てで TLS を使用できる。
codice_14 を下記のように使用する:
thread_local int number;
また非定数初期化子の使用やコンストラクタ・デストラクタを呼び出すクラスも使用できる。
thread_local int number = some_non_constexpr_function();
thread_local std::vector<int> number;
C11/C++11 より前から以下の処理系では独自に TLS を実装している。
Windows Vista および Windows Server 2008 より前の Windows では、codice_17 は実行ファイルにリンク（アーリーバインド）された DLL でのみ動作し、codice_20 でロードされる DLL では動作しない (APIは成功を返すが TLS に関する処理が行われないため保護違反もしくはデータ破壊が発生する)。
TLS の使用にはこれ以外にもルールが存在する。Thread Local Storage (TLS) | Microsoft Docs の "Rules and limitations" を参照。
C# および .NET 言語.
静的フィールドは、ThreadStaticAttributeでマークすることができる:
class FooBar
 [ThreadStatic] static int foo;
また、Thread.GetNamedDataSlot(String)メソッドによって動的にスレッド局所変数を割り当てることもできる。
Java.
Java ではスレッドローカルの変数は、クラスによって実現されている。codice_21 のオブジェクトは、オブジェクトの codice_22 や codice_23 メソッドをコールする各スレッドごとに、変数の異なるインスタンスを保持する。以下は、codice_24 オブジェクトを保持するcodice_21 を用いた例である:
ThreadLocal<Integer> local = new ThreadLocal<Integer>() {
 @Override protected Integer initialValue() {
 return 1;
};
はじめのコードで codice_21 オブジェクト codice_27 を宣言、インスタンス化し、呼び出すスレッドから他の値が格納されなければ初期値 1 を返す。以下のコードは、現在の実行スレッドから値を 1 増やす。
local.set(local.get() + 1);
codice_28は、現在のスレッドに関連付けられた codice_24 オブジェクトを返す。また、codice_30 を呼び出してスレッドに関連付けた値を設定する。なお、上記の例は J2SE 5.0 で追加されたジェネリクスと自動ボックス化を使用している。
Pascal.
Object Pascal (Delphi) や Free Pascal では、codice_31 ではなくキーワード codice_32 を用いてスレッド局所記憶変数を定義することができる。
var
 myData: Integer;
threadvar
 myThreadLocalData: Integer;
Perl.
Perl のスレッドは言語の進化に伴って CPAN で大半のコードが利用可能になった後で追加された。
その結果、Perl では既存の非スレッドサポートのコードがスレッドのサポートにより影響を受けにくいようすべての変数をスレッドローカルとして扱うことになった。逆に Perl では、スレッドで共有される変数は attribute を用いて作成することができる。
use threads;
use threads::shared;
my $localvar;
my $sharedvar :shared;
Python.
Python バージョン 2.4 以降では、threading モジュールの local クラスを使ってスレッド局所記憶を作成することができる。
import threading
mydata = threading.local()
mydata.x = 1
Ruby.
Ruby では、スレッド局所変数は []= および [] メソッドを使ってアクセスすることができる。
Thread.current[:user_id] = 1
D言語.
D言語 の D2 では、グローバル変数および静的変数がデフォルトでスレッド局所変数になった。
この場合、スレッド間で共有される変数は shared修飾子もしくは __gshared属性 を用いて作成することができる。
module sample;
int globalVar; // グローバル変数 (スレッド局所記憶)
shared(int) globalSharedVar; // (スレッド間共有)