Thread/Windows

[Thread] __declspec(thread)

Binceline 2012. 10. 18. 14:17

참조: http://kai127.springnote.com/pages/1775028


TLS

Thread Local Storage, 스레드마다 자신의 저장공간을 가진다.

 

각각의 스레드는 고유한 스택을 갖기 때문에 스택 변수( 지역 변수)는 스레드 별로 고유합니다. 예를 들어서 각각의 스레드가 같은 함수를 실행한다고 해도 그 함수에서 정의된 지역변수는 실제로 서로 다른 메모리 공간에 위치한다는 의미입니다. 그러나 정적 변수나 전역 변수의 경우에는 프로세스 내의 모든 스레드에 의해서 공유됩니다.

 

TLS는 정적, 전역 변수를 각각의 스레드에게 독립적으로 만들어 주고 싶을 때 사용하는 것입니다. 다시 말해서, 분명히 같은 문장(context)을 실행하고 있지만 실제로는 스레드 별로 다른 주소공간을 상대로 작업하는 것입니다.

 

사용방법

  1. API에서 지원하는 방식

    DLL 스스로가 자신의 TLS section 을 관리할 수 있는 Dynamic TLS 방식을 사용하는 것이 좋다.

    DWORD dwIamIndex = ::TlsAlloc();                             //공간확보

    ::TlsSetValue(dwIamIndex, pMyData);                         //데이터 저장

    BYTE* pGiveMe = (BYTE*)::TlsGetValue(dwIamIndex);   //데이터 얻기

    ::TlsFree(dwIamIndex);                                            //공간 해제

    위와 같은 API함수들을 호출하여 사용한다.

     

  2. compiler에서 지원하는 방식

__declspec(thread) smgid_t call_smid;

위와 같은 방식으로 선언한다.

문제점

  • 동적으로 Load되는 DLL에서는 사용될 수 없다. (예, LoadLibrary()를 사용)
  • 초기화가 제대로 이루어 지지 않는 문제 혹은 access violation 등이 발생한다.

 

TLS 메모리 관리 포인트

  • 자신만의 '.tls'라는 메모리 section에 위에 선언된 변수들을 등록한다.
  • 각각의 '.tls' section을 다루는 최상위 '.tls' section이 따로 존재한다.
  • 한 프로세스에서 다른 thread를 생성할 때 자신의 '.tls' section을 자식 thread에 복사한다.

    -> 자동으로 '.tls' section을 관리해주지 않기 때문에 동적 라이브러리를 호출할 때 위와 같은 문제가 발생한다.

 

 

ToDo

  • 동적로딩에 대한 이해, 정적라이브러리와 비교해서 문제점 등 파악

반응형