thread_local (C++11) 이란?
thread_local 키워드는 global이나 static과 비슷한 기능을 한다. global과 static은 프로세스 전체의 Life Cycle을 가지고 있는 반면 thread_local로 만들어진 변수는 각각의 thread에 대한 Life Cycle을 가지게 된다.
Example Code
int globalNum = 0;
thread_local int tlNum = 0;
void fn()
{
int fnNum = 2;
std::cout << "global Num: " << globalNum << std::endl;
std::cout << "thLocal Num: " << tlNum << std::endl;
globalNum++;
tlNum++;
}
int main()
{
using namespace std::chrono_literals;
int mainNum = 1;
std::thread t1(fn);
std::this_thread::sleep_for(1s);
std::thread t2(fn);
t1.join();
t2.join();
return 0;
}
실행을 해보면 global 변수는 1이 증가하였지만, thread_local 변수는 그대로 값이 0이다. 이를 메모리 관점에서 보자.
메모리 접근
컴파일러마다 다르겠지만 일반적으로 thread_local은 thread를 통해 실행시킨 함수 위쪽에 thread_local 영역이 있다.
실행 과정
1. tlNum과 globalNum을 출력한 후 tlNum과 globalNum을 각각 1씩 증가시켰으므로, tlNum = 1, globalNum = 1이 된다.
2. 1초 뒤에 새로운 thread인 t2를 만들고 함수 fn을 실행시킨다. t1과 마찬가지로 위쪽 영역에 tlNum을 가지고 있다.
3. t2가 실행시킨 fn함수에서 tlNum과 globalNum을 각각 출력한다. 이 때, static 영역에 있는 globalNum은 thread t1,t2가 공유하는 변수이기 때문에 1이 증가가 된 상태로 출력된다.
위 코드에서 thread_local 변수는 독립적인 변수이기 때문에 결과값으로 초기값 0을 출력하게 되는것이다. 또한, thread_local은 위와같이 꼭 전역 변수일 필요는 없고 함수 안에서도 사용이 가능하다.
함수 안에서 선언해도 각 변수의 위치는 위의 메모리 형태와 같다.
thread별로 사용하고 싶은 static같은 변수가 필요할 때, 예를 들면 thread 별로 싱글톤과 같은 오브젝트를 만들고 싶을 때 thread_local을 사용할 수 있다.
'C++ > Thread' 카테고리의 다른 글
[Thread] Mutex(뮤텍스) (0) | 2022.07.15 |
---|---|
[Thread] std::jthread (조이닝 쓰레드) (0) | 2022.07.13 |
[Thread] std::thread Argument (0) | 2022.06.20 |
[Thread] std::thread (0) | 2022.06.20 |
[Thread] Introduction (0) | 2022.06.13 |