c++コンパイラはC++0xでスレッドローカルストレージをどのように実装しますか
私はこれをグーグルで検索しました。しかし、私はこれについて何も見つけることができません。
誰もこれについて何か資料を持っていますか??
c++コンパイラはC++0xでスレッドローカルストレージをどのように実装しますか
私はこれをグーグルで検索しました。しかし、私はこれについて何も見つけることができません。
誰もこれについて何か資料を持っていますか??
ウィキペディアのエントリを読んでください。
スレッド ローカル ストレージは、C++ に固有のものではありません。「TLS」(スレッドローカルストレージの単なる省略形)や「スレッド固有ストレージ」(TSS)など、異なる名前で呼ばれることもあります。
ほとんどのオペレーティング システムには、スレッドごとのストレージにアクセスするための API が用意されています。たとえば、Windows には「TLS」で始まる一連の API 関数があります。内部では、Win32 は、特定の CPU レジスタ (x86 の FS) を介してアクセスできるユーザー スレッド ローカル ストレージを含む、さまざまなスレッドごとのデータ用に特別な領域を予約します。Linux は、 pthread_key_createのような名前で pthread API を介してスレッド固有のストレージを提供します。これらは通常、同様の手法を使用して実装されます。
OS がまったくサポートを提供していない可能性があります。ただし、OS が API を介してプロセス固有のスレッド ID を提供する場合、C++ ランタイム ライブラリは概念的にstd::map<thread_id, per_thread_storage>
内部のようなものを維持できます。もちろん、それでは何per_thread_storage
が問題なのかという問題があります。プログラムが静的にリンクされている場合、それは、プログラム内で要素として宣言されているすべてのスレッド ローカル ストレージ変数を持つ大きな構造体へのポインターのようなものである可能性があります。これは単純化しすぎていますが、一般的な考え方は理解できます。
スレッド ローカル ストレージ変数へのアクセスは、明らかに単なるメモリの読み取りまたは書き込みではありません。それよりもかなり複雑になる可能性があります。特定の関数でスレッド ローカル/特定のストレージを頻繁に使用する場合は、最初にスレッド ローカル ストレージ ポインターをローカル変数にコピーすることをお勧めします。
グローバル変数 (または書き込み可能な静的データ - WSD) は通常、スタック、ヒープ、およびコードとは別のメモリ ブロックに格納されます。WSD ブロックは、実行可能ファイルのコードが実行を開始する前に作成および初期化されます。
C++0x ではthread_local
、グローバル変数の個別のインスタンスがスレッドごとに作成されるようにするキーワードが導入されています。問題は、スレッドごとに異なるブロックをロードする必要があることです。
次の問題は、変数のアドレスがリンク時に固定されておらず、スレッドごとに異なることです。
この問題を回避する方法は 2 つあります。1 つはコンパイラが関数呼び出しを生成して正しいブロックを取得することであり、もう 1 つは ABI を変更して TLS ブロックをプロセッサ レジスタの 1 つに格納することです。thread_local
これをオフセットとともに使用して、正しい変数にアクセスできます。
void*
これは、プロセス ヒープに割り当てられたスレッド ローカル ブロックへのポインターを格納するために使用できる単一の値を OS が格納するライブラリ サポートとは異なります。
血みどろの詳細が必要な場合は、こちらをご覧ください。
boost::threadを使用して、さまざまなプラットフォームで TLS を移植可能に処理できます。それぞれの実装はコード内にあり、さまざまなシステムがこの領域をどのように処理するかを理解するのに役立ちます。