リンカーとライブラリ

C/C++ プログラミングインタフェース

以下の例に示すように、__thread キーワードを使用すると、変数をスレッド固有として宣言できます。

__thread int i;
__thread char *p;
__thread struct state s;

ループの最適化の際に、コンパイラは必要に応じてスレッド固有一時領域を作成することがあります。

適用性

__thread キーワードは任意の大域変数、ファイルスコープの静的変数、または関数スコープの静的変数に適用できます。常にスレッド固有である自動変数には影響を与えません。

初期化

C++ では、初期化に静的なコンストラクタが必要となる場合には、スレッド固有変数の初期化が行われないことがあります。静的なコンストラクタを必要としない限り、スレッド固有変数は通常の静的変数に有効な任意の値に初期化できます。

変数は、(スレッド固有であるかどうかにかかわらず) スレッド固有変数のアドレスに静的に初期化することはできません。

結合

スレッド固有変数の宣言と参照は外部的に行えます。この場合、通常のシンボルと同じ割り込み規則に従う必要があります。

動的な読み込みの制限

共有ライブラリは、プロセスの起動時に動的に読み込むことができます。またプロセスの起動後には、遅延読み込み、フィルタ、または dlopen(3DL) を介して、動的に読み込むことができます。スレッド固有変数に対する参照を含む共有ライブラリは、その参照を含むすべての変換ユニットが動的な TLS モデルでコンパイルされた場合に限って、起動後の読み込みが可能です。

静的な TLS モデルは、比較的高速なコードを生成します。しかし、コンパイルされた、このモデルを使用するコードは、起動後に動的に読み込まれるライブラリ内のスレッド固有変数を参照することができません。動的な TLS モデルは、あらゆる TLS を参照できます。これらのモデルについては、スレッド固有領域のアクセスモデルで説明しています。

アドレス演算子

スレッド固有変数には、アドレス演算子 & を使用できます。この演算子は、実行時に評価されて、現在のスレッド内の変数のアドレスを返します。この演算子によって取得されたアドレスは、アドレスを評価したスレッドが存在する限り、プロセス内のあらゆるスレッドで自由に使用できます。スレッドが終了した時点で、そのスレッド内のスレッド固有変数を指すポインタはすべて無効になります。

スレッド固有変数のアドレスを取得するために dlsym(3DL) を使用すると、dlsym() を呼び出したスレッド内におけるその変数のインスタンスのアドレスが返されます。