본문 바로가기
프로그래밍/시스템 프로그래밍

Thread Local Storage, TLS

by 오늘의논리 2024. 5. 2.
728x90
스레드 로컬 스토리지(Thread Local Storage, TLS)는 각 스레드가 독립적으로 사용할 수 있는 메모리 영역을 지칭한다. 이는 멀티스레드 환경에서 각 스레드가 고유한 데이터를 보유하고 유지할 수 있도록 한다. 일반적으로 전역 변수는 여러 스레드에 의해 공유되지만, TLS를 사용하면 각 스레드가 자체 데이터 복사본을 가질 수 있다. 이렇게 들으면 어렵지만 멀티쓰레드 환경에서 중요한 하나가 쓰레드를 여러 사용하는 일감이 적절하게 분배되는 것이다. 일감이 몰리면 자연적으로 경합이 일어나게 되기 때문이다. 그래서 쓰레드들이 공유하는 힙과 데이터 영역에서 데이터를 꺼내올 꺼내올때만 락을 잡고 데이터를 큼지막하게 TLS 가지고 오면 그다음엔 굳이 데이터 영역에 가지 않고 TLS 통해 데이터를 얻어온다고 생각하면 편하다. 스레드 마다 가지고 있는 스택 메모리 영역은 함수를 호출하거나 하기때문에 뭔가를 저장하거나 하는 위험한 생각이다. TSL 나만의 전역 메모리 같은 느낌이라고 생각하면 좋다.

 

TLS를 사용하는 이유:

  1. 스레드별 고유한 상태 관리: 각 스레드가 고유한 데이터를 유지하고 관리할 수 있다. 이를 통해 스레드 간 충돌을 피하고 데이터의 일관성을 유지할 수 있다.
  2. 전역 변수와의 분리: 전역 변수를 사용할 때 발생할 수 있는 스레드 간의 경쟁 조건을 피할 수 있다. TLS를 사용하면 전역 변수와 관련된 이러한 문제를 해결할 수 있다.
  3. 성능 향상: TLS를 사용하면 스레드가 자주 사용하는 데이터에 대한 접근이 더 빠를 수 있다. 이는 해당 데이터가 스레드의 로컬 메모리에 저장되어 있기 때문에 발생한다.

TLS를 사용하는 언어 및 라이브러리에는 다양한 방법이 있다. 예를 들어, C++11부터는 thread_local 키워드를 사용하여 TLS를 선언할 수 있다.

TLS를 사용할 때 주의할 점은 각 스레드에서 공유되지 않는 데이터를 사용하는 것이므로 메모리 누수나 일관성 문제가 발생하지 않도록 주의해야 다. 또한 TLS를 오용하여 과도하게 많은 데이터를 저장하는 것도 성능 문제를 초래할 수 있다.

 

아래는 쓰레드마다 각각 다른 아이디를 가지게 하고싶다라고 할때 TLS 이용해 구현해 것이다.

 

#include <iostream>
#include <atomic>
#include <vector>
#include <mutex>
using namespace std;

thread_local int LThreadId = 0;

void ThreadMain(int _iThreadId)
{
    LThreadId = _iThreadId;

    while (true)
    {
        cout << "My Id is " << LThreadId << endl;
        this_thread::sleep_for(1s);
    }
}



int main()
{
    vector<thread> threads;

    for (int i = 0; i < 10; ++i)
    {

        int threadId = i + 1;
        threads.push_back(thread(ThreadMain, threadId));
    }

    for (thread& t : threads)
    	t.join();

	return 0;
}
728x90

'프로그래밍 > 시스템 프로그래밍' 카테고리의 다른 글

메모리 모델  (0) 2024.05.02
CPU 파이프 라인  (0) 2024.04.30
캐시  (0) 2024.04.30
future  (0) 2024.03.13
Event  (0) 2024.03.06

댓글