본문 바로가기
C#/쓰레드

1. C# 스레드 생성과 병렬 처리 이해

by 공부봇 2025. 1. 24.
반응형

1. 스레드란 무엇인가?

스레드는 프로그램 실행의 기본 단위입니다.

  • 프로세스(Process): 실행 중인 프로그램의 인스턴스입니다. 프로세스는 독립적인 메모리 공간과 자원을 갖고 실행됩니다.
  • 스레드(Thread): 프로세스 내부에서 실행되는 작은 작업 단위입니다. 한 프로세스는 여러 개의 스레드를 가질 수 있으며, 스레드는 프로세스의 메모리와 자원을 공유합니다.

2. 스레드와 프로세스의 차이

구분 프로세스 스레드
정의 실행 중인 프로그램 프로세스 내부에서 실행되는 작업 단위
자원 사용 각 프로세스는 독립적인 메모리와 자원을 갖습니다. 프로세스의 자원을 공유합니다.
오버헤드 새로운 프로세스를 생성하면 많은 자원이 필요합니다. 새로운 스레드는 프로세스보다 가볍고, 더 적은 자원을 사용합니다.
병렬 처리 여러 프로세스는 병렬로 실행되지만, 각각 독립적입니다. 같은 프로세스 내에서 여러 스레드가 병렬로 실행되며, 서로 협력할 수 있습니다.
안전성 프로세스 간 메모리는 독립적이므로 상대적으로 안전합니다. 공유 메모리를 사용하기 때문에 동기화 문제나 데이터 충돌이 발생할 가능성이 있습니다.

3. 기본 스레드 샘플 코드

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        // 1. 스레드 생성 (PrintNumbers 메서드 실행)
        Thread thread = new Thread(PrintNumbers);
        thread.Start();

        // 메인 스레드 작업
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine($"Main Thread: {i}");
            Thread.Sleep(500); // 500ms 대기
        }
    }

    // 새 스레드에서 실행할 작업
    static void PrintNumbers()
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine($"Worker Thread: {i}");
            Thread.Sleep(1000); // 1초 대기
        }
    }
}
 
 
 

코드 분석 및 결과 확인

  1. Thread thread = new Thread(PrintNumbers);
    • PrintNumbers 메서드를 실행하는 새로운 스레드를 생성합니다.
  2. thread.Start();
    • 새 스레드를 시작합니다.
  3. 메인 스레드는 동시에 다른 작업(숫자 출력)을 실행합니다.
  4. 결과:
    • "Main Thread"와 "Worker Thread"가 동시에 출력됩니다.
    • 출력 순서는 실행 환경에 따라 다를 수 있습니다.

실행 결과 예시:

Main Thread: 0
Worker Thread: 0
Main Thread: 1
Main Thread: 2
Worker Thread: 1
Main Thread: 3
Main Thread: 4
Worker Thread: 2
Worker Thread: 3
Worker Thread: 4

4. 고급 스레드 샘플 코드

(1) 람다 표현식을 사용한 스레드

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        // 람다 표현식을 사용해 스레드 작업 정의
        Thread thread = new Thread(() =>
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine($"Lambda Thread: {i}");
                Thread.Sleep(1000); // 1초 대기
            }
        });
        thread.Start();

        // 메인 스레드 작업
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine($"Main Thread: {i}");
            Thread.Sleep(500); // 500ms 대기
        }
    }
}

코드 분석 및 결과 확인

  1. 람다 표현식:
    • 새 스레드에서 실행할 작업을 람다 표현식으로 정의합니다. 메서드를 따로 만들 필요가 없습니다.
  2. thread.Start();:
    • 새 스레드를 시작합니다.
  3. 결과:
    • 메인 스레드와 람다 표현식을 통해 실행된 스레드가 동시에 작업을 수행합니다.

실행 결과 예시:

Main Thread: 0
Lambda Thread: 0
Main Thread: 1
Main Thread: 2
Lambda Thread: 1
Main Thread: 3
Main Thread: 4
Lambda Thread: 2
Lambda Thread: 3
Lambda Thread: 4

(2) 매개변수가 있는 스레드

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        // 스레드에 매개변수를 전달하기 위한 작업
        Thread thread = new Thread(PrintNumbers);
        thread.Start(10); // 매개변수 10 전달

        // 메인 스레드 작업
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine($"Main Thread: {i}");
            Thread.Sleep(500); // 500ms 대기
        }
    }

    static void PrintNumbers(object max)
    {
        int limit = (int)max; // object 타입 매개변수를 int로 변환
        for (int i = 0; i < limit; i++)
        {
            Console.WriteLine($"Worker Thread: {i}");
            Thread.Sleep(1000); // 1초 대기
        }
    }
}

코드 분석 및 결과 확인

  1. 스레드 매개변수 전달:
    • thread.Start(10);로 매개변수 10을 전달합니다.
    • PrintNumbers 메서드는 object 타입의 매개변수를 받아서 내부에서 변환합니다.
  2. 결과:
    • 메인 스레드는 병렬로 작업을 수행하며, 새 스레드는 매개변수에 따라 작업 횟수를 조정합니다.

실행 결과 예시:

Main Thread: 0
Worker Thread: 0
Main Thread: 1
Main Thread: 2
Worker Thread: 1
Main Thread: 3
Main Thread: 4
Worker Thread: 2
Worker Thread: 3
Worker Thread: 4
Worker Thread: 5
Worker Thread: 6
Worker Thread: 7
Worker Thread: 8
Worker Thread: 9

(3) 스레드 우선순위 변경

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        // 낮은 우선순위의 스레드
        Thread lowPriorityThread = new Thread(() =>
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine($"Low Priority Thread: {i}");
                Thread.Sleep(1000); // 1초 대기
            }
        });
        lowPriorityThread.Priority = ThreadPriority.Lowest;

        // 높은 우선순위의 스레드
        Thread highPriorityThread = new Thread(() =>
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine($"High Priority Thread: {i}");
                Thread.Sleep(1000); // 1초 대기
            }
        });
        highPriorityThread.Priority = ThreadPriority.Highest;

        lowPriorityThread.Start();
        highPriorityThread.Start();
    }
}

코드 분석 및 결과 확인

  1. 스레드 우선순위:
    • lowPriorityThread.Priority = ThreadPriority.Lowest 로 낮은 우선순위를 설정합니다.
    • highPriorityThread.Priority = ThreadPriority.Highest 로 높은 우선순위를 설정합니다.
  2. 결과:
    • 실행 환경에 따라 높은 우선순위의 스레드가 더 자주 실행됩니다.
    • 하지만 스레드 우선순위는 절대적인 것이 아니라 힌트로 사용됩니다.

실행 결과 예시:

High Priority Thread: 0
Low Priority Thread: 0
High Priority Thread: 1
High Priority Thread: 2
Low Priority Thread: 1
High Priority Thread: 3
High Priority Thread: 4
Low Priority Thread: 2
Low Priority Thread: 3
Low Priority Thread: 4

5. 요약

  • 스레드는 병렬 처리를 가능하게 해주는 기본 단위입니다.
  • 프로세스와 자원을 공유하며, 효율적인 멀티태스킹을 구현할 수 있습니다.
  • C#에서는 Thread 클래스를 사용해 스레드를 생성, 관리합니다.
  • 고급 스레드 활용법:
    1. 람다 표현식으로 간결하게 작업 정의.
    2. 매개변수 전달로 유연성 제공.
    3. 우선순위 조정으로 특정 스레드 작업 우선시.
반응형