スレッドローカルストレージ (TLS) を理解する

それぞれのスレッドには、そのスレッドだけからしかアクセスできない、固有のデータを格納する領域を確保することができます。 それが スレッドローカルストレージ (Thread Local Storage, TLS) です。

ここでは動作実験をすることによって、 TLS を理解しましょう。

TLS の使用方法

TLS の使用方法は簡単です。4 つの TLS API だけで OK です。パラメータもほとんどありません。

  1. TlsAlloc を呼び出して TLS スロットのインデックスを取得する
  2. TlsSetValue を、インデックスとデータを渡して呼び出す
  3. データを取得するときは、TlsGetValue を呼び出す。
    このときの引数は Tls スロットのインデックスです。
  4. TLS のデータが不要になったら、解放する TLS インデックスを渡して TlsFree を呼び出す。

これだけです。実際のコードは次のようになります。

#include <stdio.h>
#include <windows.h>

int main( int argc, char* argv[] ) {

     //
     // Get TLS Index
     //

     DWORD dwIndex = TlsAlloc();

     if( TLS_OUT_OF_INDEXES == dwIndex ) {
         printf( "TlsAlloc() Failed. gle=%u\n", GetLastError() );
         return 1;
     }

     printf( "TlsAlloc returned %u\n", dwIndex );

     //
     // Set a value to TLS
     //

     char szMsg[] = "Hello, World\n";

     if( !TlsSetValue(dwIndex, (LPVOID) szMsg) ) {
         printf( "TlsSetValue Failed. glt = %u\n", GetLastError() );
         return 1;
     }

     //
     // Get a value from TLS
     //

     char* szRet = (char*) TlsGetValue( dwIndex );

     if( !szRet ) {
         printf("TlsGetValue Failed.\n");
         return 1;
     }

     printf( "%s\n", szRet);

     //
     // Free the Tls slot.
     //

     if( !TlsFree(dwIndex) ) {
         printf("TlsFree Failed.\n");
         return 1;
     }

     return 0;

}

ちなみに、実際に TLS はいったいどこに格納されるのでしょう。

実は TLS は TIB (Thread Information Block) に格納されます。 TIB は FS レジスタから 0x18 オフセットにあります。 さらにそこから、オフセット 0xe10 の場所に TLS スロットがあります。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Web/DB プログラミング徹底解説