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

Mutex

by samosa 2024. 11. 16.

Mutex는 .NET에서 다중 스레드 및 다중 프로세스 간의 상호 배제(Mutual Exclusion)를 보장하기 위해 사용되는 동기화 객체이다. 스레드나 프로세스가 Mutex를 소유하고 있을 때 다른 스레드나 프로세스는 해당 Mutex가 해제될 때까지 대기해야 한다. 이는 운영 체제의 커널 수준에서 관리되며, 높은 신뢰성을 제공한다.

주요 특징

  • 커널 모드 의존성: Mutex는 운영 체제의 커널 모드에서 동작하는 객체로, 사용자 모드에서 커널 모드로 전환이 필요하다. 이로 인해 컨텍스트 스위칭이 발생하고 CPU 리소스 소모가 증가해 성능 오버헤드가 발생할 수 있다.
  • 프로세스 간 동기화: Mutex는 단일 프로세스 내에서뿐만 아니라 다중 프로세스 환경에서도 동기화가 가능하다. 이는 Mutex가 다른 동기화 메커니즘보다 강력한 이유 중 하나이다.

커널 모드와 사용자 모드

  • 커널 모드는 운영 체제의 핵심 기능에 직접 접근할 수 있는 특권 모드로, 모든 자원에 접근할 수 있어 성능 오버헤드가 크다.
  • 사용자 모드는 제한된 권한을 가지며 애플리케이션이 안전하게 실행될 수 있도록 보호한다.

Mutex는 커널 모드에서 동작하므로 사용자 모드에서 작동하는 다른 동기화 메커니즘(예: Monitor, SpinLock)에 비해 상대적으로 속도가 느릴 수 있다. 따라서 높은 성능이 요구되는 단일 프로세스 동기화에는 Monitor 등의 메커니즘이 더 적합할 수 있다.

예제 코드 (Task 기반)

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    // 전역 Mutex 객체 생성
    private static Mutex _mutex = new Mutex();
    private static int _sharedResource = 0;

    static async Task Main(string[] args)
    {
        // 두 개의 작업(Task)을 시작
        Task task1 = Task.Run(() => AccessResource("Task 1"));
        Task task2 = Task.Run(() => AccessResource("Task 2"));

        // 두 작업이 완료될 때까지 대기
        await Task.WhenAll(task1, task2);

        Console.WriteLine("작업이 완료되었습니다.");
    }

    static void AccessResource(string taskName)
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine($"{taskName}이(가) 리소스를 기다리고 있습니다...");

            // Mutex를 획득
            _mutex.WaitOne();
            try
            {
                Console.WriteLine($"{taskName}이(가) 리소스를 획득했습니다.");
                _sharedResource++;
                Console.WriteLine($"{taskName}이(가) 리소스를 사용하는 중... (_sharedResource: {_sharedResource})");
                Thread.Sleep(1000); // 리소스 사용 시뮬레이션
            }
            finally
            {
                // Mutex 해제
                _mutex.ReleaseMutex();
                Console.WriteLine($"{taskName}이(가) 리소스를 해제했습니다.");
            }

            // 다음 반복 전에 약간의 대기
            Thread.Sleep(500);
        }
    }
}

코드 설명

  • _mutex.WaitOne(): Mutex를 획득하고 임계 구역에 진입한다. 다른 스레드나 프로세스는 대기해야 한다.
  • _mutex.ReleaseMutex(): Mutex를 해제하여 다른 대기 중인 스레드나 프로세스가 임계 구역에 진입할 수 있도록 한다.
  • 커널 모드 전환: WaitOne()ReleaseMutex() 호출 시 커널 모드로 전환되며, 이 전환은 성능 오버헤드가 발생할 수 있다.

성능 고려사항

  • 장점: Mutex는 강력한 동기화가 필요할 때, 특히 여러 프로세스 간의 동기화가 필요한 경우 적합하다.
  • 단점: 커널 모드 전환으로 인한 성능 오버헤드가 발생하므로, 단일 프로세스 내의 단순 동기화에는 Monitor나 사용자 모드 동기화 메커니즘을 사용하는 것이 더 효율적이다.

요약

Mutex는 다중 스레드 및 다중 프로세스 환경에서의 강력한 동기화를 제공하는 커널 모드 기반 객체이다. 프로세스 간 동기화가 필요한 경우에 적합하지만, 성능 요구 사항에 따라 더 가벼운 동기화 메커니즘을 사용하는 것이 바람직할 수 있다.

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

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