본문 바로가기

C#

[C#] Multi-threading Programming - Thread Local Storage(TLS)

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ServerCore
{
    class Program
    {
        //TLS
        static object _lock = new object();
        static ThreadLocal<string> ThreadName = new ThreadLocal<string>();
        
        //static String ThreadName으로 선언할 경우, ThreadName.Value는 모두 같은 값이 나옴.
        //ThreadLocal<>: Thread마다 고유한 공간을 생성.
        //한 뭉텅이씩 일을 가져와서 하는 것. 이 경우 Lock을 하지 않아도 부담 없음.
        //전역에 접근하는 횟수를 줄이는 등의 이점이 있어 부하를 줄이는 데 도움이 됨.

        static void WhoAmI()
        {
            ThreadName.Value = ($"{Thread.CurrentThread.ManagedThreadId}");

            Thread.Sleep(1000); //1초 대기

            Console.WriteLine($"Thread num.{ThreadName.Value}" +
                $"the order is {Thread.CurrentThread.Priority}");
        }

        public static void Main(string[] args)
        {
            lock(_lock)
            {
                Thread.CurrentThread.Priority  = ThreadPriority.Lowest;
                ThreadPool.QueueUserWorkItem(obj => { });
                Console.WriteLine($"Thread num.{Thread.CurrentThread.ManagedThreadId} " +
                    $"the order is {Thread.CurrentThread.Priority}");
            }

            Thread.CurrentThread.Priority = ThreadPriority.Highest;
            Parallel.Invoke(WhoAmI, WhoAmI, WhoAmI, WhoAmI, WhoAmI);
        }
    }
}

 

실행 결과

 

 

ThreadName.Value = ($"");

를 통해 스레드의 값을 지정해주어도 된다.

 

 

게임개발에서 Lock이 굉장히 많이 쓰이는데

TLS를 사용할 경우 각 스레드마다 로컬 순서를 정할 수 있어

굳이 Lock을 2차적으로 사용하지 않아도 되어 부담이 적다.

 

 

 

 

다만 CurrentThread.Priority를 좀 더 자세히 다루어보고 싶다.

 

Thread.CurrentThread.Priority = ThreadPriority.{};

{} = {Lowest, Normal(default), Highest, ...}

 

public System.Threading.ThreadPriority Priority { get; set; }

 

▼ 마이크로소프트 공식 페이지에서 설명하는 내용

https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.priority?view=net-8.0

 

Thread.Priority Property (System.Threading)

Gets or sets a value indicating the scheduling priority of a thread.

learn.microsoft.com

 

다음에 이걸 활용해서 더 세밀하게 각 스레드의 순서를 지정해보고자 한다.

 

 

 

 

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버