본문 바로가기
Function/C#

C# Thread 사용방법 정리

by wawManager 2024. 8. 28.
728x90

안녕하세요.

C#에서 Thread는 여러 작업을 동시에 수행할 수 있는 멀티태스킹의 기초를 제공합니다. 스레드는 프로그램 내에서 독립적으로 실행되는 경량 프로세스입니다. 여러 스레드를 사용하면 CPU의 여러 코어를 활용하여 프로그램의 성능을 향상시키거나, 사용자 인터페이스가 응답성을 유지하도록 할 수 있습니다.

# 기본적인 스레드 생성 및 시작
C#에서 Thread 클래스를 사용하여 새로운 스레드를 만들고 시작할 수 있습니다.

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        // 스레드가 실행할 메서드를 지정하여 스레드 생성
        Thread myThread = new Thread(MyThreadMethod);

        // 스레드 시작
        myThread.Start();

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

    // 새 스레드에서 실행될 메서드
    static void MyThreadMethod()
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine("MyThreadMethod: " + i);
            Thread.Sleep(100); // 100ms 동안 대기
        }
    }
}


결과:
MyThreadMethod: 0
Main Thread: 0
MyThreadMethod: 1
Main Thread: 1
MyThreadMethod: 2
Main Thread: 2
MyThreadMethod: 3
Main Thread: 3
MyThreadMethod: 4
Main Thread: 4


- Thread myThread = new Thread(MyThreadMethod);:
  - MyThreadMethod라는 메서드를 실행할 새 스레드를 만듭니다.
- myThread.Start();:
  - 새 스레드를 시작합니다. 이 메서드를 호출하면 MyThreadMethod가 독립적으로 실행됩니다.
- Thread.Sleep(100);:
  - 스레드를 지정된 시간(밀리초) 동안 일시 중지시킵니다. 여기서는 100ms 동안 스레드가 대기합니다.

# 스레드의 상태 관리
스레드의 상태를 관리할 수 있는 여러 메서드가 제공됩니다.

- Join(): 현재 스레드가 완료될 때까지 호출한 스레드가 대기합니다.
- IsAlive: 스레드가 아직 실행 중인지를 나타냅니다.
- Abort(): 스레드의 실행을 강제 종료합니다. (이 메서드는 권장되지 않으며, 예외를 발생시킬 수 있습니다.)

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        Thread myThread = new Thread(MyThreadMethod);
        myThread.Start();

        // 스레드가 끝날 때까지 대기
        myThread.Join();
        Console.WriteLine("MyThread has completed.");

        Console.WriteLine("Main Thread Ends.");
    }

    static void MyThreadMethod()
    {
        for (int i = 0; i < 3; i++)
        {
            Console.WriteLine("MyThreadMethod: " + i);
            Thread.Sleep(500);
        }
    }
}


- myThread.Join();:
  - 메인 스레드는 myThread가 완료될 때까지 대기합니다. MyThreadMethod가 실행된 후 "MyThread has completed." 메시지가 출력됩니다.

# 멀티스레딩의 주의점: 공유 자원 동기화

여러 스레드가 동일한 자원에 접근할 때, 동기화 문제(경쟁 조건)가 발생할 수 있습니다. 이를 방지하기 위해 lock 문을 사용하여 자원 접근을 보호할 수 있습니다.

using System;
using System.Threading;

class Program
{
    static object lockObject = new object();
    static int counter = 0;

    static void Main()
    {
        Thread t1 = new Thread(Increment);
        Thread t2 = new Thread(Increment);

        t1.Start();
        t2.Start();

        t1.Join();
        t2.Join();

        Console.WriteLine("Final counter: " + counter);
    }

    static void Increment()
    {
        for (int i = 0; i < 100000; i++)
        {
            lock (lockObject)
            {
                counter++;
            }
        }
    }
}


- lock (lockObject):
  - counter 변수에 접근할 때 다른 스레드가 동시에 접근하지 못하도록 잠금을 설정합니다. 이를 통해 경쟁 조건을 방지합니다.
- 경쟁 조건:
  - 여러 스레드가 동시에 counter 변수에 접근하면 예기치 않은 결과가 발생할 수 있습니다. lock 문을 사용하여 이를 방지합니다.

# 스레드 풀 사용

스레드를 직접 관리하는 대신, ThreadPool을 사용하여 간단하게 스레드를 관리할 수 있습니다. ThreadPool은 미리 준비된 스레드를 사용하여 작업을 처리합니다.

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        // 스레드 풀에 작업 큐잉
        ThreadPool.QueueUserWorkItem(ThreadPoolMethod);

        Console.WriteLine("Main Thread Ends.");
        Thread.Sleep(1000); // 잠시 대기하여 스레드 풀의 작업이 완료될 시간 제공
    }

    static void ThreadPoolMethod(object state)
    {
        Console.WriteLine("ThreadPool Method Executing...");
    }
}




- ThreadPool.QueueUserWorkItem:
  - 스레드 풀에 작업을 큐잉합니다. ThreadPoolMethod가 스레드 풀에서 실행됩니다.

# 결론

C#에서 스레드는 복잡한 프로그램에서 병렬 처리를 수행하고 응답성을 유지하는 데 중요한 도구입니다. 하지만 잘못된 스레드 사용은 동기화 문제나 예기치 않은 버그를 초래할 수 있으므로 신중한 설계가 필요합니다. Thread 클래스나 ThreadPool을 사용하여 스레드를 적절하게 관리하는 것이 중요하며, 필요한 경우 lock을 사용하여 공유 자원을 보호해야 합니다.

 

 

 

(chat gpt 참고)

728x90

'Function > C#' 카테고리의 다른 글

C# Panel 컨트롤에 폼 상속시키기: 다중 화면 전환 구현하기  (0) 2024.10.17
C# Dialog문 사용법 정리  (0) 2024.08.29
C# HEX코드 활용법  (0) 2024.08.27
C# ASCII 코드 사용법  (0) 2024.08.26
C# List vs Dictionary 비교  (0) 2024.08.25