카테고리 없음

스레드(Thread)와 스레드 풀(ThreadPool)에 대해 알아보자

근본넘치는개발자 2024. 11. 13. 23:59

오늘은 스레드(Thread)와 스레드 풀(ThreadPool)에 대해 정리해 보고자 합니다.

 

원래는 Task에 대해서 먼저 글을 작성하고자 했는데 

Task의 동작 원리가 Thread와 ThreadPool 개념을 알아야 하더군요.

 

재미있게도 자꾸 뭔가 거꾸로 공부해 나가는 듯한 느낌이;;

스레드 

스레드는 CPU 시간을 할당받는 기본 단위

기본적으로 모든 프로그램은 메인 스레드를 가지고 있음

 

장점

메모리를 절약할 수 있다.

 

->같은 프로세스 내의 스레드들은 메모리를 공유하기 때문.

코드, 데이터, 힙 영역 공유 / 각 스레드는 독립적인 스택 영역 보유

 

 

단점 

반환 값을 받을 수 없다.

작업 완료 대기 기능이 없다.

실행 중인 작업 취소 불가능하다.

 

 

 

ThreadPool

 

미리 생성된 스레드들의 집합 / 재사용함으로 성능 향상

 

 

예시 

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

class ThreadExamples
{
    //기본적인 스레드 생성과 실행
    public void BasicThreadExample()
    {
        // 스레드 생성 방법 1: Thread 생성자 사용
        Thread thread1 = new Thread(() =>
        {
            Console.WriteLine($"Thread 1 실행 중: {Thread.CurrentThread.ManagedThreadId}");
            Thread.Sleep(1000);
        });
        thread1.Start();

        // 스레드 생성 방법 2: ThreadStart 델리게이트 사용
        ThreadStart threadStart = new ThreadStart(() =>
        {
            Console.WriteLine($"Thread 2 실행 중: {Thread.CurrentThread.ManagedThreadId}");
            Thread.Sleep(1000);
        });
        Thread thread2 = new Thread(threadStart);
        thread2.Start();

        // 스레드 생성 방법 3: ParameterizedThreadStart 사용
        Thread thread3 = new Thread(new ParameterizedThreadStart((object obj) =>
        {
            Console.WriteLine($"Thread 3 실행 중: {Thread.CurrentThread.ManagedThreadId}, 파라미터: {obj}");
            Thread.Sleep(1000);
        }));
        thread3.Start("Hello Thread!");

        // 모든 스레드 종료 대기
        thread1.Join();
        thread2.Join();
        thread3.Join();
    }

  

    //스레드 풀 사용 예시
    public void ThreadPoolExample()
    {
        // 기본적인 ThreadPool 사용
        ThreadPool.QueueUserWorkItem(state =>
        {
            Console.WriteLine($"ThreadPool 작업 1: {Thread.CurrentThread.ManagedThreadId}");
            Thread.Sleep(1000);
        });

        // 상태 객체를 전달하는 ThreadPool 사용
        ThreadPool.QueueUserWorkItem(state =>
        {
            Console.WriteLine($"ThreadPool 작업 2: {state}");
            Thread.Sleep(1000);
        }, "Custom State");

        // 병렬 작업 처리
        for (int i = 0; i < 5; i++)
        {
            int taskNum = i;
            ThreadPool.QueueUserWorkItem(state =>
            {
                Console.WriteLine($"병렬 작업 {taskNum}: {Thread.CurrentThread.ManagedThreadId}");
                Thread.Sleep(1000);
            });
        }
    }

  
}

 

 

마무리 

찾아보니 지금은 직접적인 Thread 클래스 사용을 권장하지 않기도 하고

스레드의 단점을 극복하기 위해 Task가 만들어진 후

Task가 표준으로 자리 잡아 굳이 사용하지는 않는 듯합니다.

 

하지만 예전 시스템에는 남아 있을 수도 있으니

한번 보자는 의미에서 간단하게 정리해봤습니다.

 

사실 설명하면 프로세스와 비교도 하고, 더 길게 할 수도 있지만

Task를 이해하기 위한 내용 정도로 마무리했습니다.

 

전공을 하면서 스레드에 관한 내용을 듣긴 했지만 

또 이렇게 정리하니까 새롭네요;;

 

참고한 자료

https://youtu.be/5a3H11SVylw?si=ZJ3ZBa8wAGSZk3XU

 

 

https://youtu.be/74O_F0aLIqo?si=rko6lpfp_jVprd9X

https://youtu.be/alN1qED3TNA?si=UpiJumILuAD579Dq