| 영역 | 쓰레드 간 공유 여부 | 비고 |
|---|---|---|
| Stack | ❌ 쓰레드별로 분리됨 | 함수 호출 스코프 종료 시 자동 소멸 |
| Heap | ✅ 모든 쓰레드 공유 | 명시적 동기화 필요 (락, atomic 등) |
| Data (.data, .bss) | ✅ 모든 쓰레드 공유 | 전역, static 변수 |
| TLS (Thread Local Storage) | ❌ 쓰레드별로 분리됨 | 전역처럼 생겼지만 쓰레드 독립 |
// TLS를 사용하지 않았다면
// 전역 변수 LThreadId가 모든 쓰레드에서 공유되어 값이 꼬일 수 있음
// TLS 사용 시 → 쓰레드마다 LThreadId 복사본을 가짐 (경합 없음!)
thread_local int32_t LThreadId = 0;
| 구분 | Stack | TLS |
|---|---|---|
| 사용 목적 | 함수 내부 임시 변수 | 쓰레드 고유의 전역 변수 |
| 유효 범위 | 함수 실행 중 | 쓰레드 생존 중 |
| 안전성 | 함수 종료 시 해제됨 (불안정) | 안전하게 유지됨 |
| 공유 여부 | 공유되지 않음 | 공유되지 않음 |
🐯 "호랑이가 먹이를 자기 굴에 가져가 혼자 먹는 것처럼, TLS는 쓰레드 전용 저장소야!"
#include <iostream>
#include <thread>
#include <vector>
thread_local int32_t LThreadId = 0;
void ThreadMain(int32_t id)
{
LThreadId = id;
while (true)
{
std::cout << "Hi! I am Thread " << LThreadId << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main()
{
std::vector<std::thread> threads;
for (int32_t i = 0; i < 5; ++i)
{
int32_t id = i + 1;
threads.emplace_back(ThreadMain, id);
}
for (auto& t : threads)
t.join();
}
각 쓰레드는
LThreadId를 독립적으로 가지며, 출력이 섞이지 않고 정확하게 나오는 것을 확인할 수 있다.
❓ 다른 쓰레드가 특정 쓰레드의 TLS 값을 수정해야 할 상황이 오면?
Rookiss 답변 요약:
즉, TLS는 "내가 나 혼자 쓸 값"에만 적합하다.
__declspec(thread) int32_t value;
thread_local int32_t value = 0;