スレッドローカルストレージ (TLS) を理解する
それぞれのスレッドには、そのスレッドだけからしかアクセスできない、固有のデータを格納する領域を確保することができます。 それが スレッドローカルストレージ (Thread Local Storage, TLS) です。
ここでは動作実験をすることによって、 TLS を理解しましょう。
TLS の使用方法
TLS の使用方法は簡単です。4 つの TLS API だけで OK です。パラメータもほとんどありません。
- TlsAlloc を呼び出して TLS スロットのインデックスを取得する
- TlsSetValue を、インデックスとデータを渡して呼び出す
- データを取得するときは、TlsGetValue を呼び出す。
このときの引数は Tls スロットのインデックスです。 - 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 スロットがあります。