Advanced C++

[C++] thread_local 키워드

로파이 2022. 4. 26. 20:47

https://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables

 

Storage class specifiers - cppreference.com

The storage class specifiers are a part of the decl-specifier-seq of a name's declaration syntax. Together with the scope of the name, they control two independent properties of the name: its storage duration and its linkage. auto or (until C++11)no specif

en.cppreference.com

 

thread_local 키워드

스레드마다 고유한 저장소를 지칭하는 변수를 말한다. static 키워드와 마찬가지로 처음 실행될 때 초기화되며 각기 다른 쓰레드가 처음 실행할 때마다 초기화된다.

static 키워드와 마찬가지로 스레드 내에서 전역 특성이 있어 같은 스레드가 thread_local 변수를 포함하는 함수를 여러번 실행하면 변화가 중첩되어 반영된다.

void test_thread_local_storage(std::string threadName)
{
	thread_local int a = 0;

	++a;
	{
		std::lock_guard<std::mutex> lk(mtx);
		std::cout << threadName << " : " << a << std::endl;
	}
}


void test_program(std::function<void(std::string)> func, std::string threadName)
{
	for (int i = 0; i < 10; ++i)
	{
		func(threadName);
	}
}
int main()
{
	std::vector<std::thread> threads;
	for (int i = 0; i < 3; ++i)
	{
		std::string threadName = "Thread " + std::to_string(i);
		threads.emplace_back([threadName]() { test_program(test_thread_local_storage, threadName); });
	}
	
	for (int i = 0; i < 3; ++i)
	{
		threads[i].join();
	}

	return 0;
}

각 스레드는 int a 변수에대해 0~10의 증감을 실행한다. 변수 a는 스레드에서 전역이다.

 

vs static 키워드 변수

void test_static_storage(std::string threadName)
{
	static int a = 0;

	++a;
	{
		std::lock_guard<std::mutex> lk(mtx);
		std::cout << threadName << " : " << a << std::endl;
	}
}

static 변수는 스레드와 상관없이 전역적으로 한 번 초기화되고 공유되어 사용되어진다. 따라서 모든 스레드에서 변화가 반영된다.