쓰레드는 힙 영역과 데이터 영역을 공유한다.
Thread마다 가질 수 있는 공유한 영역을 만드려면 Thread Local Storage(TLS) 를 사용하면 된다.
다음 예제는 TLS로 생성한 영역에 이름을 넣고 출력하는 예제이다.
Sleep을 걸어서 다른 쓰레드가 값을 건드리는지 확실하게 체크한다.
class ThreadProgram
{
static ThreadLocal<string> ThreadName = new ThreadLocal<string>();
//static string ThreadName;
static void WhoAmI()
{
ThreadName.Value = $"My name is {Thread.CurrentThread.ManagedThreadId}";
Thread.Sleep(1000);
Console.WriteLine(ThreadName.Value);
}
static void Main(string[] args)
{
ThreadPool.SetMinThreads(1, 1);
ThreadPool.SetMaxThreads(3, 3);
Parallel.Invoke(WhoAmI, WhoAmI, WhoAmI, WhoAmI, WhoAmI);
}
}
결과:
My name is 7
My name is 1
My name is 6
My name is 4
My name is 7 (일을 처리한 쓰레드가 다시 WhoAmI 함수를 호출한다)
만약 동일한 코드에서 TLS를 사용하지 않는다면?
class ThreadProgram
{
//static ThreadLocal<string> ThreadName = new ThreadLocal<string>();
static string ThreadName;
static void WhoAmI()
{
ThreadName = $"My name is {Thread.CurrentThread.ManagedThreadId}";
Thread.Sleep(1000);
Console.WriteLine(ThreadName);
}
static void Main(string[] args)
{
ThreadPool.SetMinThreads(1, 1);
ThreadPool.SetMaxThreads(3, 3);
Parallel.Invoke(WhoAmI, WhoAmI, WhoAmI, WhoAmI, WhoAmI);
}
}
결과:
My name is 4
My name is 4
My name is 4
My name is 6
My name is 6
다른 쓰레드가 ThreadName 값을 바꾸고 있음을 알 수 있다.
다음은 TLS를 Lazy 방식으로 사용하는 예제이다.
ThreadName을 생성하지 않은 경우 등록된 함수를 호출해서 초기화한다.
class ThreadProgram
{
static ThreadLocal<string> ThreadName = new ThreadLocal<string>(() => { return $"My name is {Thread.CurrentThread.ManagedThreadId}"; });
static void WhoAmI()
{
if (ThreadName.IsValueCreated)
Console.WriteLine(ThreadName.Value + " (repeat)");
else
Console.WriteLine(ThreadName.Value); // lazy 방식으로 동작한다.
}
static void Main(string[] args)
{
ThreadPool.SetMinThreads(1, 1);
ThreadPool.SetMaxThreads(3, 3);
Parallel.Invoke(WhoAmI, WhoAmI, WhoAmI, WhoAmI, WhoAmI);
// TLS 종료
ThreadName.Dispose();
}
}
결과:
My name is 1
My name is 6
My name is 7
My name is 6 (repeat)
My name is 7 (repeat)
'프로그래밍 > Game Dev' 카테고리의 다른 글
[Phaser] Animation, TileMap (0) | 2023.09.28 |
---|---|
[Node.js] 간단한 멀티 슈팅게임 소스 분석 (0) | 2023.09.26 |
[C#] AutoResetEvent (0) | 2023.08.26 |
[C#] SpinLock (0) | 2023.08.26 |
[C#] Interlocked (0) | 2023.08.26 |
댓글