게임엔진/Unity

[Unity] ThreadPool (스레드풀)

ShovelingLife 2024. 1. 3. 20:42

스레드를 사용하기 위해선 다음과 같이 선언 해줘야한다.

using System.Threading;

스레드 선언하기

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은 스레드가 종료될 때 까지를 기다린다. 즉, 스레드가 종료되었는 지를 확인하고 작업을 종료한다.

스레드 풀 사용하기

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 사용하기

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

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

 

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

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

 

https://yerim-coding.tistory.com/33