본문 바로가기
공부/게임서버

ManualResetEvent

by samosa 2024. 11. 15.

ManualResetEvent는 .NET에서 스레드 간의 동기화를 제공하는 동기화 객체이다. AutoResetEvent와 비슷하지만, 주요 차이점은 이벤트가 수동으로 리셋될 때까지 신호 상태를 유지한다는 점이다. 이를 통해 한 번 신호 상태로 전환되면 여러 스레드가 이 신호를 받을 수 있다.

특징

  • 수동 리셋: ManualResetEvent는 한 번 Set() 메서드를 호출하여 신호 상태(true)로 설정되면, Reset() 메서드를 호출할 때까지 신호 상태를 유지한다. 따라서 한 번 설정된 신호는 여러 스레드가 이를 인식하고 임계 구역에 진입할 수 있다.
  • 대기 스레드 관리: WaitOne() 메서드를 통해 스레드가 신호 상태가 될 때까지 대기한다. Set()이 호출되면 모든 대기 중인 스레드가 깨어나고, Reset()이 호출될 때까지 신호 상태가 유지된다.

사용 예제

다음은 ManualResetEvent의 동작을 보여주는 간단한 예제 코드이다.

using System;
using System.Threading;

class Program
{
    // ManualResetEvent 객체 생성 (초기 상태: 비신호 상태)
    private static ManualResetEvent _manualEvent = new ManualResetEvent(false);

    static void Main(string[] args)
    {
        // 두 개의 스레드 시작
        Thread worker1 = new Thread(Worker);
        Thread worker2 = new Thread(Worker);
        worker1.Start();
        worker2.Start();

        Console.WriteLine("메인 스레드: 작업 스레드가 실행을 기다린다...");

        // 3초 후 신호를 보냄
        Thread.Sleep(3000);
        Console.WriteLine("메인 스레드: 신호를 보낸다!");
        _manualEvent.Set(); // 모든 대기 중인 스레드가 깨어난다.

        // 2초 후 신호를 다시 리셋
        Thread.Sleep(2000);
        Console.WriteLine("메인 스레드: 신호를 리셋한다.");
        _manualEvent.Reset(); // 이벤트를 다시 비신호 상태로 전환

        // 스레드가 종료될 때까지 대기
        worker1.Join();
        worker2.Join();
    }

    static void Worker()
    {
        Console.WriteLine("작업 스레드: 대기 중...");
        _manualEvent.WaitOne(); // 신호를 받을 때까지 대기
        Console.WriteLine("작업 스레드: 신호를 받고 작업을 시작!");
    }
}

코드 설명

  • ManualResetEvent 초기화: new ManualResetEvent(false)로 초기화하여 처음에는 비신호 상태로 설정한다.
  • Set() 메서드: 신호 상태로 전환하여 WaitOne()에서 대기 중인 모든 스레드를 깨운다.
  • Reset() 메서드: 비신호 상태로 전환하여 다시 대기 상태로 만든다.
  • WaitOne() 메서드: 스레드는 WaitOne()이 호출될 때까지 대기하며, 신호를 받으면 실행을 계속한다.

ManualResetEventAutoResetEvent의 차이점

  • ManualResetEvent: 신호가 설정되면 수동으로 Reset()이 호출될 때까지 신호 상태를 유지하므로, 여러 스레드가 한 번의 신호로 깨어날 수 있다.
  • AutoResetEvent: 한 번 신호가 전달되면 자동으로 비신호 상태로 돌아가, 단일 스레드만 신호를 받을 수 있다.

사용 사례

  • ManualResetEvent는 여러 스레드가 한 번의 신호로 동시에 시작되어야 하는 경우에 적합하다. 예를 들어, 초기화가 완료된 후 여러 스레드가 동시에 작업을 시작하도록 신호를 보내는 경우에 사용할 수 있다.
  • AutoResetEvent는 한 번에 하나의 스레드만 깨우는 동기화가 필요한 경우 적합하다.

요약

ManualResetEvent는 스레드 간 동기화에 사용되며, 신호 상태를 유지해 여러 스레드가 이를 인식할 수 있다. Set()으로 신호를 설정하고, Reset()으로 비신호 상태로 전환하여 제어한다. 이 기능은 여러 스레드가 동일한 시점에서 동작을 시작해야 하는 상황에 유용하다.

'공부 > 게임서버' 카테고리의 다른 글

ReaderWriterLock  (2) 2024.11.16
Mutex  (0) 2024.11.16
AutoResetEvent  (0) 2024.11.14
Monitor 사용 시 주의사항  (0) 2024.11.13
Thread.Sleep 과 Thread.Yield  (0) 2024.11.12