멀티 스레드 환경에서 TLS를 사용하지 않은 경우
동시성 문제가 발생하는 모든 구역에 Lock을 걸어버리면 데이터의 안전성은 보장되겠지만 상황에 따라서 문제가 발생할 수 있다.
예를 들어서 게임로직에 A던전, B던전, C던전에 대한 코드가 작성이 되어 있는데
갑자기 클라이언트 단에서 모든 유저가 A던전에 입장을 하려고 할 때 A 던전에 대한 게임로직이 바빠져서 평상시에 입장하는 것보다 시간이 더 오래 걸리게 될 수 있다.
이러한 상황에서는 오히려 멀티 스레드로 환경을 구축하는게 더 안 좋게 된다.
TLS를 사용해서 해결
TLS( 스레드 로컬 스토리지 )를 사용하면 프로세스가 전역(Global) 인덱스를 사용하여 액세스할 수 있는 각 스레드에 대해 고유한 데이터를 제공할 수 있다.
각 쓰레드에 TLS 슬롯을 만들고 Globlal Data 영역에는 각 쓰레드의 TLS 슬롯과 연결되는 인덱스를 할당한다. 각 쓰레드는 TLS 슬롯 인덱스에 Globlal Data 영역 인덱스에 대한 포인터(주소)를 저장하고 그 포인터를 이용해 값을 가져와 각 쓰레드의 지역변수에 저장한다.
코드
class Program
{
// Global 영역에 각각의 쓰레드가 독립적으로 TLS를 가짐
static ThreadLocal<string> ThreadName = new ThreadLocal<string>();
// TLS를 설정하지 않고 Global 데이터로 두게 되면 모든 스레드가 접근 할 수 있기 때문에 데이터가 변경 될 수 있음
// static string ThreadName;
static void WhoAmI()
{
// 쓰레드 이름을 추가하는 작업이 각각의 TLS에서 독립적으로 수행됨
ThreadName.Value = $"My name is {Thread.CurrentThread.ManagedThreadId}";
Thread.Sleep(1000);
Console.WriteLine(ThreadName.Value);
}
static void Main(string[] args)
{
Parallel.Invoke(WhoAmI, WhoAmI, WhoAmI, WhoAmI, WhoAmI, WhoAmI);
// Global 영역에 있는 TLS를 모두 해제
ThreadName.Dispose();
}
}
'게임개발 > 게임서버' 카테고리의 다른 글
멀티 쓰레드 프로그래밍 (0) | 2024.04.17 |
---|---|
멀티쓰레드 Lock 구현 방식 (2) | 2024.01.15 |
소켓 프로그래밍 (0) | 2023.10.29 |
ReadWriteLock (0) | 2023.10.26 |
교착 상태(Deadlock) (0) | 2023.10.17 |