[C# 서버] 쓰레드 생성

Yerin·2023년 9월 19일

C# 게임 서버

목록 보기
1/13

쓰레드 생성하기

Thread

using System;
using System.Threading;

namespace SeverCore
{   
    class Program {
        static void MainThread()
        {
            Console.WriteLine("Hello Thread!");
        }
        static void Main(string[] args)
        {
            Thread t = new Thread(MainThread);
            t.Start();
            Console.WriteLine("Hello World!");
        }
    } 
}

C#은 C++과는 다르게 foreground 가 default 이다.
따라서 아래와 같이 쓰레드를 무한 루프로 만든다면 영원히 끝나지 않을 것이다.

namespace SeverCore
{   
    class Program {
        static void MainThread()
        {
            while(true)
                Console.WriteLine("Hello Thread!");
        }
        static void Main(string[] args)
        {
            Thread t = new Thread(MainThread);
            t.Start();
            Console.WriteLine("Hello World!");
        }
    } 
}

쓰레드의 IsBackground = true 설정을 이용하여 Main 함수가 종료하면
쓰레드도 종료하도록 한다.

namespace SeverCore
{   
    class Program {
        static void MainThread()
        {
            while(true)
                Console.WriteLine("Hello Thread!");
        }
        static void Main(string[] args)
        {
            Thread t = new Thread(MainThread);
            t.IsBackground = true;
            t.Start();
            Console.WriteLine("Hello World!");
        }
    } 
}

t.Join() 을 넣어 실행 해당 쓰레드가 종료될 때까지 기다리는 함수를 넣을 수도 있다.

namespace SeverCore
{   
    class Program {
        static void MainThread()
        {
            while(true)
                Console.WriteLine("Hello Thread!");
        }
        static void Main(string[] args)
        {
            Thread t = new Thread(MainThread);
            t.Name = "Test Thread";
            t.IsBackground = true;
            t.Start();
            Console.WriteLine("Waiting for Thread!");
            t.Join();
            Console.WriteLine("Hello World!");
        }
    } 
}

ThreadPool

간단한 동작을 사용하기 위해 쓰레드를 이용하고 싶은 경우에는?
쓰레드는 부담이 클 경우

ThreadPool.QueueUserWorkItem 를 이용한다.

namespace SeverCore
{
    class Program
    {
        static void MainThread(object state)
        {
            for (int i = 0; i < 5; i++)
                Console.WriteLine("Hello Thread!");
        }
        static void Main(string[] args)
        {
            ThreadPool.QueueUserWorkItem(MainThread);

            while (true)
            { 
            //main 함수를 계속하기 위함
            }
        }
    }
}

쓰레드 수랑 cpu 코어의 수를 맞춰주는 것이 좋다.

ThreadPool은 최대로 동시에 돌릴 수 있는 쓰레드 수를 제한한다.
그러므로 긴 작업을 할당할 경우 먹통이 될 위험이 있다.

먹통이 되는 경우

namespace SeverCore
{
    class Program
    {
        static void MainThread(object state)
        { 
            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);

            while (true)
            { 
            
            }
        }
    }
}

해결 방안
해당 작업이 오래 걸릴 것이라는 것을 알려줌.

Task t = new Task(() => { while (true) { } }, TaskCreationOptions.LongRunning);
t.Start();

Task

namespace SeverCore
{
    class Program
    {
        static void MainThread(object state)
        { 
            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++)
            {
                Task t = new Task(() => { while (true) { } }, TaskCreationOptions.LongRunning);
                t.Start();
            }

            ThreadPool.QueueUserWorkItem(MainThread);
            while (true)
            { }
        }
    }
}
profile
재밌는 코딩 공부

0개의 댓글