TLS(Thread Local Storage)

쓰레드마다 갖고 있는 로컬 저장소 != 스택

a1.png

  • 동물원의 호랑이를 생각해보자
  • 공통 영역에서 큼지막한 덩어리를 가져온 다음 필요한걸 꺼내쓰면 처음 가져올 때만 경합이 발생하고 큰 덩어리에서 고를 때는 경합이 필요 없다.

TLS 예제

  • get_id() 로 받는 난수 id가 아닌 쓰레드마다 직접 id를 할당하고 싶다면?
thread_local int32 LThreadId = 0; //TLS
mutex m;

void ThreadMain(int32 threadId)
{
    LThreadId = threadId;

    while(true)
    {
        {
            lock_guard<mutex> lock(m);
            cout << "Hi! I am Thread " << LThreadId << endl;
        }
        this_thread::sleep_for(1s);
    }
}

int main()
{
    vector<thread> threads;
    
    for(int32 i = 0 ; i < 10 ; i++)
    {
        int32 threadId = i + 1;
        threads.push_back(thread(ThreadMain, threadId));
    }
    
    for (thread& t : threads)
        t.join();
        
    return 0;
}

실행 결과

Hi! I am Thread 1
Hi! I am Thread 4
Hi! I am Thread 2
Hi! I am Thread 5
Hi! I am Thread 3
Hi! I am Thread 6
Hi! I am Thread 8
Hi! I am Thread 7
Hi! I am Thread 9
Hi! I am Thread 10
...
  • 각 쓰레드 마다 자신의 id를 TLS에 저장했음을 확인할 수 있다.
  • 이를 응용해서 쓰레드별 Stack이나 Queue를 구현할 수도 있다.

이어지는 궁금증…

  • TLS는 스택영역과는 별개의 개념이라고 했다.
  • 그럼 각 쓰레드의 TLS 공간은 전역변수 데이터 영역에 저장되며 다른 쓰레드에 의해 침범될 수 있을까?

이에 관련한 문답을 링크 : Stack overflow 에서 찾았다.