E D R S I H C RSS
ID
Password
Join
우리는 자유롭기 위해서 법에 묶여 사는 것이다. ―키케로

 * MSDN에서 인용했음을 밝힙니다.

하나의 프로세스상의 모든 쓰레드들은 가상의 주소공간과 해당 프로세스의 전역변수들을 공유한다. 쓰레드 함수상의 지역변수들은 함수가 실행될동안 각 쓰레드에 local한 특성을 가진다. 어쨌거나 쓰레드 함수에 의해 사용되는 static 또는 전역 변수들은 모든 쓰레드상에서도 같은 값을 가지게 된다. (역주 : 즉, 한 쓰레드에서 값을 변경하면 다른 쓰레드에서는 변경된 값으로 나타난다) Thread Local Storage를 사용하면 각 쓰레드를 위한 변수의 "유니크한 복사본"을 생성할 수 있다. TLS를 사용하면 한 쓰레드는 인덱스를 할당하며, 그 인덱스는 "유일한 복사본을 받기위한" 프로세스의 어떤 쓰레드에 의해서도 사용될 수 있다.
TLS를 구현하기 위한 단계는 다음과 같다.

  1. 프로세스나 DLL 초기화때 TLS 인덱스를 할당하기 위해서 TlsAlloc함수를 사용하라.
  2. TLS 인덱스를 사용할 필요가 있는 각 쓰레드를 위해 동적 스토리지(역자 : 동적으로 할당되는 메모리)를 할당하라. 그리고 TLS 인덱스와 동적으로 할당된 메모리를 연관시키기위해 TlsSetValue 함수를 사용하라.
  3. 쓰레드가 그 자신의 메모리를 억세스할 필요가 있을때 TlsGetValue함수를 사용할때 TLS 인덱스를 지정해서 그 메모리의 포인터를 얻어라.
  4. TLS 인덱스와 연결된 동적 메모리를 더이상 사용할 필요가 없을때에는 인덱스는 반드시 해제하여야 한다. TLS 인덱스를 사용하는 모든 쓰레드가 종료하였을때, TlsFree함수를 사용하여 TLS 인덱스를 해제해라.

TLS_MINIMUM_AVAILABLE 매크로 상수는 TLS 인덱스의 각 프로세스당 최소 개수를 정의한다. 이 최소개수는 모든 시스템을 통틀어 64이상 임이 보장된다.

  • Windows 2000: 프로세스당 최대 1088 TLS 인덱스 가능.
  • Windows NT 4.0 또는 그 이전 : 프로세스당 최대 64 TLS 인덱스 가능.

DLL내에서 TLS를 사용하는 것은 이상적인 방법이다. DLL에 부착되는 프로세스 또는 쓰레드의 입장에서 DllMain함수내에 TLS 초기화 명령들을 실행하라. DLL로 새로운 프로세스가 attach되면, 그 프로세스를 위한 TLS 인덱스를 할당하기 위해 진입역할을 하는 함수내에 TlsAlloc함수를 호출하라. 그리고 전역변수 내에 TLS 인덱스를 저장하라. 이것은 DLL에 attach된 프로세스 자신만이 억세스할수 있게 된다. (private속성을 가진다.)

When a new thread attaches to the DLL, allocate dynamic memory for that thread in the entry-point function, and use TlsSetValue with the TLS index from TlsAlloc to save private data to the index. Then you can use the TLS index in a call to TlsGetValue to access the private data for the calling thread from within any function in the DLL. When a process detaches from the DLL, call TlsFree.

Thread local storage (TLS) enables multiple threads of the same process to use an index allocated by the TlsAlloc function to store and retrieve a value that is local to the thread. In this example, an index is allocated when the process starts. When each thread starts, it allocates a block of dynamic memory and stores a pointer to this memory by using the TLS index. The TLS index is used by the locally defined CommonFunc function to access the data local to the calling thread. Before each thread terminates, it releases its dynamic memory.

#include <stdio.h> 
#include <windows.h> 
 
#define THREADCOUNT 4 
DWORD dwTlsIndex; 
 
VOID ErrorExit(LPTSTR); 
 
VOID CommonFunc(VOID) 
{ 
   LPVOID lpvData; 
 
// Retrieve a data pointer for the current thread. 
 
   lpvData = TlsGetValue(dwTlsIndex); 
   if ((lpvData == 0) && (GetLastError() != 0)) 
      ErrorExit("TlsGetValue error"); 
 
// Use the data stored for the current thread. 
 
   printf("common: thread %d: lpvData=%lx\n", 
      GetCurrentThreadId(), lpvData); 
 
   Sleep(5000); 
} 
 
DWORD WINAPI ThreadFunc(VOID) 
{ 
   LPVOID lpvData; 
 
// Initialize the TLS index for this thread. 
 
   lpvData = (LPVOID) LocalAlloc(LPTR, 256); 
   if (! TlsSetValue(dwTlsIndex, lpvData)) 
      ErrorExit("TlsSetValue error"); 
 
   printf("thread %d: lpvData=%lx\n", GetCurrentThreadId(), lpvData); 
 
   CommonFunc(); 
 
// Release the dynamic memory before the thread returns. 
 
   lpvData = TlsGetValue(dwTlsIndex); 
   if (lpvData != 0) 
      LocalFree((HLOCAL) lpvData); 
 
   return 0; 
} 
 
DWORD main(VOID) 
{ 
   DWORD IDThread; 
   HANDLE hThread[THREADCOUNT]; 
   int i; 
 
// Allocate a TLS index. 
 
   if ((dwTlsIndex = TlsAlloc()) == -1) 
      ErrorExit("TlsAlloc failed"); 
 
// Create multiple threads. 
 
   for (i = 0; i < THREADCOUNT; i++) 
   { 
      hThread[i] = CreateThread(NULL, // no security attributes 
         0,                           // use default stack size 
         (LPTHREAD_START_ROUTINE) ThreadFunc, // thread function 
         NULL,                    // no thread function argument 
         0,                       // use default creation flags 
         &IDThread);              // returns thread identifier 
 
   // Check the return value for success. 
      if (hThread[i] == NULL) 
         ErrorExit("CreateThread error\n"); 
   } 
 
   for (i = 0; i < THREADCOUNT; i++) 
      WaitForSingleObject(hThread[i], INFINITE); 
 
   return 0; 
} 
 
VOID ErrorExit (LPTSTR lpszMessage) 
{ 
   fprintf(stderr, "%s\n", lpszMessage); 
   ExitProcess(0); 
} 


Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2010-10-28 12:42:54
Processing time 0.3295 sec