본문 바로가기
게임 서버/Thread

[c#/유니티] 스레드(Thread)와 스레드풀(ThreadPool)

by 얘리밍 2022. 12. 5.
320x100
728x90

 

 

 

 

프로세스와 스레드에 대해 먼저 알아보자.

 

 

프로세스 : 현재 실행 중인 프로그램

스레드 : 운영 체제가 프로세서 시간을 할당하는 기본 단위 / 명령어를 실행하기 위한 스케쥴링 단위 

 

 

쉽게 말해서, 스레드는 작업자라고 생각하면 된다. 

어떠한 업무가 주어졌을 때, 그 일을 수행하는 작업자가 바로 스레드 이다.

 

 

 

 


 

 

 

 

* NameSpace(네임스페이스)  선언하기 

using System.Threading;

스레드를 사용하기 위해서 다음과 같이 선언해주자

 

 

1) 스레드 선언하기 

Thread t = new Thread(MainTread);

스레드를 사용하기 위해 다음과 같이 스레드 생성자를 만든다. 

넘겨주는 MainTread 함수 또한 생성한다. 

static void MainTread(object state)
 {
 	Console.WriteLine("Hello Thread!");     
 }

 

 

 

기본 스레드foreground에서 실행되는 형태이다.

스레드의 이름을 설정하고 싶으면 Name 을 활용한다.

 

static void Main(string[] args)
{
	Thread t = new Thread(MainTread);
    
	t.Name = "Test Thread"; //이름을 설정한다.
    	t.Start(); //스레드 실행
    
    
    	Console.WriteLine("Waiting for Thread!"); //메인 작업
}

 

 

 

 

이 때, 다음과 같이 스레드를 무한 반복으로 실행하면

메인 종료와 상관없이 계속해서 실행된다..

(foreground 스레드는 부모 스레드가 종료되어도 함께 종료되지 않고 계속 동작한다 )

 

static void MainTread()
{
        //메인 함수와 상관없이 지속해서 실행됨(영영 실행..)  
 	while(true) 
		Console.WriteLine("Hello Thread!");

 

 

계속해서 실행되는 스레드

 

 

 

이를 백그라운드에서 실행하면, 스레드는 실행 여부와 상관없이 메인 함수가 종료되면 같이 종료된다. 

t.IsBackground = true;   //기본 값은 false이다.
t.Start();

t.Join();   //스레드가 끝날 때 까지 기다림

 

join은 스레드가 종료될 때 까지를 기다린다. 즉, 스레드가 종료되었는 지를 확인하고 작업을 종료한다.

 

 

 

 

 

 

 

2) 스레드 풀(ThreadPool) 사용하기 

 

 

thread 와 threadPool의 차이에 대해 먼저 알아보면, 

    thread

  • 스레드를 사용할 때는 개수를 제한하지를 않는다. 
  • 하지만 스레드 수와 cpu core 수를 맞춰주는 것이 좋다 

   

    threadPool

  • 스레드 풀을 사용하면  최대로 돌릴 수 있는 스레드를 제한한다.
  • 아주 많은 개수를 실행시켜도 기존의 프로세스를 수행한 다음, 이후에 일을 수행한다. 

 

 

ThreadPool은 단기로 실행하는 것에 대해 유용하다. 

static void MainTread(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); //최대 스레드 개수
            
    		ThreadPool.QueueUserWorkItem(MainTread);

 

thread와는 다르게 object 인자를 명시해 주어야 하며 스레드의 개수를 제한하므로

setMinThread setMaxThread를 통해 최소, 최대 스레드를 설정해 주면 된다. 

 

 

 

스레드 풀을 사용하여

최대 치 만큼 일을 할당하면 

다음과 같이 이후의 일을 하지 못하는 것을 볼 수 있다.

 

 

하지만 다음과 같이 네 개의 스레드만 할당하여 남는 것이 있다면, 

나머지 작업을 원활하게 수행 가능하다.

for (int i = 0; i < 4; i++)
	ThreadPool.QueueUserWorkItem((obj) => { while (true) { } });

 

 

 

 

이처럼 모든 스레드가 할당 되었을 때, 일이 막히는 상황을 해결하는 방법은 무엇일까

Task를 사용하면 된다. 

 

 

 

 

 

 

 

3) Task 사용하기 

 

for(int i=0; i<5; i++)
        {
            //아주 오래걸리는 작업에 대해 
            Task t = new Task(() => { 
            	while (true) { } }, TaskCreationOptions.LongRunning);
            t.Start();
        }

 

TaskCreationOPtions.LongRunning 옵션을 설정해주면, 긴 작업이 수행되는 작업에 대해서도

일을 원활하게 수행 가능하다. 

 

이렇게 ThreadPool의 부족현상을 해결할 수 있다. 

 

 

 

 

 

 

 

 

 

 

 

출처 및 참고 : https://www.inflearn.com/course/%EC%9C%A0%EB%8B%88%ED%8B%B0-mmorpg-%EA%B0%9C%EB%B0%9C-part4

728x90
반응형