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

c# 스레드 기초

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

C# 스레드 기초 강좌

C#에서 스레드는 여러 작업을 동시에 실행할 수 있도록 도와주는 중요한 기능입니다. 이 강좌에서는 스레드의 생성부터 관리, 종료까지 다양한 기초 작업을 배우고, 각각의 주제에 대해 예제 코드를 통해 학습하겠습니다.


1. 스레드 생성

C#에서 스레드를 생성하려면 System.Threading.Thread 클래스를 사용합니다.

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        Thread thread = new Thread(new ThreadStart(DoWork));
        thread.Start();
    }

    static void DoWork()
    {
        Console.WriteLine("스레드에서 작업 실행!");
    }
}

설명:

  • ThreadStart 대리자를 사용해 실행할 메서드를 지정합니다.
  • Start() 메서드로 스레드를 시작합니다.

2. 스레드 일시 정지

스레드를 잠시 멈추고 싶을 때는 Thread.Sleep 메서드를 사용합니다.

class Program
{
    static void Main()
    {
        Thread thread = new Thread(() =>
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine($"작업 {i + 1}");
                Thread.Sleep(1000); // 1초 대기
            }
        });
        thread.Start();
    }
}

설명:

  • Thread.Sleep(milliseconds)는 지정된 시간 동안 현재 스레드를 일시 정지합니다.

3. 스레드 대기

스레드가 작업을 끝낼 때까지 기다리려면 Join 메서드를 사용합니다.

class Program
{
    static void Main()
    {
        Thread thread = new Thread(() =>
        {
            Console.WriteLine("작업 중...");
            Thread.Sleep(2000); // 2초 대기
            Console.WriteLine("작업 완료!");
        });
        thread.Start();

        thread.Join(); // 스레드가 종료될 때까지 대기
        Console.WriteLine("메인 스레드 종료");
    }
}

설명:

  • Join 메서드는 스레드가 작업을 끝낼 때까지 메인 스레드의 실행을 일시 정지합니다.

4. 스레드 중단

스레드를 중단하려면 Abort 메서드를 사용하나, 이는 권장되지 않습니다. 대신, 플래그를 사용하여 스레드를 안전하게 종료합니다.

class Program
{
    static bool stopThread = false;

    static void Main()
    {
        Thread thread = new Thread(() =>
        {
            while (!stopThread)
            {
                Console.WriteLine("작업 중...");
                Thread.Sleep(500);
            }
            Console.WriteLine("스레드 종료");
        });
        thread.Start();

        Console.WriteLine("아무 키나 누르면 스레드를 중지합니다.");
        Console.ReadKey();
        stopThread = true;
    }
}

설명:

  • 플래그(stopThread)를 통해 스레드 루프를 종료합니다.

5. 스레드 상태 조사

스레드의 상태를 확인하려면 Thread.ThreadState 속성을 사용합니다.

class Program
{
    static void Main()
    {
        Thread thread = new Thread(() =>
        {
            Console.WriteLine("작업 중...");
            Thread.Sleep(1000);
        });

        Console.WriteLine($"스레드 상태: {thread.ThreadState}");
        thread.Start();
        Console.WriteLine($"스레드 상태: {thread.ThreadState}");
    }
}

6. 스레드 우선순위 설정

스레드의 우선순위를 조정하려면 Thread.Priority 속성을 사용합니다.

class Program
{
    static void Main()
    {
        Thread thread = new Thread(() =>
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("작업 중...");
            }
        });

        thread.Priority = ThreadPriority.Highest; // 우선순위 설정
        thread.Start();
    }
}

7. 포그라운드 스레드와 백그라운드 스레드

백그라운드 스레드는 애플리케이션 종료 시 함께 종료됩니다.

class Program
{
    static void Main()
    {
        Thread thread = new Thread(() =>
        {
            while (true)
            {
                Console.WriteLine("백그라운드 작업 중...");
                Thread.Sleep(1000);
            }
        });

        thread.IsBackground = true; // 백그라운드 스레드 설정
        thread.Start();

        Console.WriteLine("메인 스레드 종료");
    }
}

8. 스레드에 파라미터 전달

스레드에 파라미터를 전달하려면 ParameterizedThreadStart 또는 람다식을 사용할 수 있습니다.

class Program
{
    static void Main()
    {
        Thread thread = new Thread((object message) =>
        {
            Console.WriteLine($"메시지: {message}");
        });
        thread.Start("안녕하세요!");
    }
}

9. lock 키워드로 잠금 처리

다중 스레드 환경에서 리소스 충돌을 방지하려면 lock을 사용합니다.

class Program
{
    static readonly object locker = new object();

    static void Main()
    {
        Thread thread1 = new Thread(PrintNumbers);
        Thread thread2 = new Thread(PrintNumbers);

        thread1.Start();
        thread2.Start();
    }

    static void PrintNumbers()
    {
        lock (locker)
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine($"스레드 {Thread.CurrentThread.ManagedThreadId}: {i}");
                Thread.Sleep(500);
            }
        }
    }
}

10. Monitor 클래스 사용

Monitor를 사용해 고급 잠금 처리를 수행할 수 있습니다.

class Program
{
    static readonly object locker = new object();

    static void Main()
    {
        Thread thread1 = new Thread(PrintNumbers);
        Thread thread2 = new Thread(PrintNumbers);

        thread1.Start();
        thread2.Start();
    }

    static void PrintNumbers()
    {
        Monitor.Enter(locker);
        try
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine($"스레드 {Thread.CurrentThread.ManagedThreadId}: {i}");
                Thread.Sleep(500);
            }
        }
        finally
        {
            Monitor.Exit(locker);
        }
    }
}

11. 스레드 예외 처리

스레드에서 예외를 처리하려면 내부에서 try-catch를 사용합니다.

class Program
{
    static void Main()
    {
        Thread thread = new Thread(() =>
        {
            try
            {
                throw new Exception("스레드에서 발생한 예외");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"예외 처리됨: {ex.Message}");
            }
        });

        thread.Start();
    }
}

마무리

이 강좌에서는 C# 스레드의 기초적인 사용법과 다양한 기능에 대해 배웠습니다. 여러 작업을 효율적으로 처리할 때 스레드를 적절히 활용해 보세요. 추가적인 질문이나 요청 사항이 있다면 언제든지 알려주세요!

반응형