[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 쓰레드 생성

참치와돌고래·2022년 8월 12일
0
post-custom-banner

Thread

본격적으로 코드에서 쓰레드 실습을 해보자.

class Threads
    {
        static void MainThread()
        {
            while(true)
                Console.WriteLine("Hello Thread");
        }
        static void Main(string[] args)
        {
            Thread t = new Thread(MainThread);
            //t.IsBackground = true; 기본적으론 false로 되어 있어, 쓰레드가 계속 실행된다.
            t.Start();
            Console.WriteLine("Hello main");
        }
    }

쓰레드를 만들려면 실행할 함수를 넣어야하며, Start()를 이용해 시작할 수 있다.
해당 코드를 실행하면, Hello Thread!만 주구장창 나와 프로그램이 끝나지 않을 것이다. 이땐 t.IsBackground를 true로 해주면 메인 함수 종료시 쓰레드도 같이 종료하게끔 할 수 있다.

  • t.Join()을 넣어주면 해당 쓰레드가 끝날 때까지 기다린 후 다음 코드가 실행된다.
  • t.Name으로 쓰레드의 이름도 정해줄 수 있다.

쓰레드는 개수가 제한이 없고, 간단한 작업을 하는데 쓰레드를 쓴다면 CPU에게 큰 부담이 될 수 있다. 그럴 땐 후술할 ThreadPool를 이용하자.

ThreadPool

강의의 비유로 설명하자면, 인력 사무소 같은 느낌. 즉 정해진 인원이 QueueUserWorkItem을 통해 실행되면 그 작업이 끝날 때까지는 다른 일을 할 수 없는 개념. 코드를 통해 살펴보자.

static void MainThread(object _obj)
        {
            for(int i=0;i<5;i++)
                Console.WriteLine("Hello Thread");
        }
        static void Main(string[] args)
        {
            ThreadPool.SetMinThreads(1, 1);
            ThreadPool.SetMaxThreads(5, 5);
            for(int i = 0; i < 5; i++)
            {
                ThreadPool.QueueUserWorkItem((obj) => { while(true){} });
            }
            ThreadPool.QueueUserWorkItem(MainThread);
            //최대 인력 5명이 전부 무한루프에 빠져, MainThread 실행이 안된다.
            while (true)
            {

            }
        }

본 코드에선 SetMinThreads, SetMaxThreads를 통해 쓰레드의 최소, 최대 개수를 정하였다. 그런데, 최대 인원이 5명인 상황에서 어마어마하게 오래 걸리는 일을 맡긴다음, Hello Thread를 5번 출력하는 일을 준다면 어떻게 될까? 일을 맡길 수 있는 사람이 없으니 해당 쓰레드가 실행될 일은 없을 것이다.(당연히, 무한 루프 일거리를 주는 반복문 코드를 4번 실행하게 한다면, 실행될 것이다.)

Task

이 상황에서 Task를 이용한 코드를 보자.

static void MainThread(object _obj)
        {
            for(int i=0;i<5;i++)
                Console.WriteLine("Hello Thread");
        }
        static void Main(string[] args)
        {
            
            //Task도 ThreadPool 넣어 관리
            ThreadPool.SetMinThreads(1, 1);
            ThreadPool.SetMaxThreads(5, 5);
            //직원이 할 일감을 정의
            
            for (int i = 0; i < 5; i++)
            {
                //TaskCreationOptions.LongRunning을 이용하면 별도로 관리할 수 있다.
                Task t = new Task(() => { while (true) { } }, TaskCreationOptions.LongRunning);
                t.Start();
            }
            ThreadPool.QueueUserWorkItem(MainThread);
            while (true)
            {

            }
        }

해당 코드를 실행한다면 의도한 대로 Hello Thread가 5번 출력될 것이다. Task에서의 TaskCreationOptions.LongRunning을 이용하여 별도의 쓰레드를 추가로 요청하였기 때문이다. 어떻게 보면 Task는 Thread와 ThreadPool의 장점만 취합한 친구라고 보면 될 듯싶다.

post-custom-banner

0개의 댓글