사용자 도구

사이트 도구


kb:threadlocalstorage

Thread Local Storage

Thread Local Storage, 줄여서 TLS는 그 이름이 의미하는 대로, 각 스레드별로 고유한 데이터 저장 영역을 말한다. pthread 계열에서는 TLS라고 부르지 않고, Thread-Specific Data라고 부르는 모양이다. Per-Thread Data라고 부르는 경우도 있다. -_- 왠만하면 용어 정도는 통일해주면 좋을 텐데.

같은 프로세스 안의 스레드는 컨텍스트 같은 특별한 데이터를 제외하고는 메모리를 공유한다. 그런데 이런 기능을 피하고 싶을 때가 있다. 즉 각각의 스레드에서 변수를 공통된 방식으로 액세스하되, 그 변수가 다른 스레드에 의해 액세스되는 것은 막고 싶을 때가 있다는 것이다. (무슨 말이야… -_-)

대표적인 경우가 데이터베이스를 액세스하는 멀티 스레드 애플리케이션이다. 하나의 연결 객체로 여러 스레드에서 쿼리를 하는 경우, 대부분 연결이 끊어지던지, 애플리케이션이 다운되던지 둘 중의 하나다.

컴파일러가 제공하는 storage-class modifier를 이용하는 방법과, 명시적으로 API를 이용하는 방법이 있다.

Storage Class Modifier

__declspec(thread) int test;

모든 스레드에서 test라는 이름으로 변수를 액세스하지만, 실제로는 각각의 스레드마다 다른 test 변수의 사본이 존재하게 된다.

TLS APIs

DWORD index = ::TlsAlloc();                // 할당
::TlsSetValue(index, &test);               // 저장 
BYTE* pRef = (BYTE*)::TlsGetValue(index);  // 로드
::TlsFree(index);                          // 해제 

즉 index 값을 변수의 alias로 여기면 된다.

장단점

척 보기에도 storage-class modifier가 간단하고 좋아 보이지만, 늘 그렇듯이 어느 쪽이 장점만 가지고 있다면, 다른 쪽이 존재할 필요가 없다. 즉 storage-class modifier는 TLS에 비해 다음과 같은 단점을 가진다.

  • 동적으로 로드되는 DLL에서는 사용할 수가 없다.
  • 소스가 플랫폼(정확히 말하자면 컴파일러) 종속적이게 된다. (어디까지나 개인적인 의견… 다른 컴파일러에서도 지원하면 그만.)

왜 동적으로 로드되는 DLL에서 storage-class modifier를 사용할 수 없는지는 다른 곳에서 찾아보기 바란다. 어쨌든 핵심은 속편하게 쓸려면 DLL에서는 그냥 Tls 함수군을 사용하는 것이 낫다는 말이다.

링크

kb/threadlocalstorage.txt · 마지막으로 수정됨: 2014/11/10 20:43 저자 excel96