C#/TIL(Today I Learned)

2025-04-02 <Race Condition 해소를 위한 전략>

프린스 알리 2025. 4. 1.

🔒 BASIC

1. Monitor (lock)

  • C#의 대표적인 임계 구역(critical section) 보호 방법.
  • 한 번에 하나의 스레드만 진입 가능.
  • 내부적으로 Monitor.Enter()Monitor.Exit() 호출.
  • 유저 모드에서 동작하므로 오버헤드는 낮고 빠르지만, 블로킹이 발생하면 결국 커널 모드로 전환됨.
lock (myLockObj)
{
    // 임계 구역
}

💪 근성 (계속 들이대는 방식)

1. SpinLock

  • lock과 유사하지만 스레드가 잠금을 얻을 때까지 CPU를 계속 소비하며 반복 검사(spin)함.
  • 커널 모드 진입 없이 작동하기 때문에 짧은 시간 동안만 잠금이 필요한 경우 고성능.
  • 다만, 장시간 락을 잡고 있으면 CPU 점유율 급등 가능.
SpinLock spinLock = new SpinLock();
bool lockTaken = false;

try
{
    spinLock.Enter(ref lockTaken);
    // 임계 구역
}
finally
{
    if (lockTaken) spinLock.Exit();
}

🧏‍♂️ 양보 (기꺼이 기다리는 방식)

3. Thread.Yield / Thread.Sleep / Context Switching

  • Thread.Yield(): 현재 스레드가 동일 우선순위의 다른 스레드에게 CPU 양보
  • Thread.Sleep(0) 또는 Thread.Sleep(n): 현재 스레드 일정 시간 정지. 다음 타임슬라이스까지 양보.
  • 이들은 직접적인 동기화 기법은 아니지만, CPU 자원을 적절히 양보하여 경쟁 상태를 줄이는 전략으로 쓰인다.
  • Context Switching은 OS가 스레드 간 CPU를 전환하는 작업으로, 비용이 크다. 무분별한 context switch 유도는 오히려 성능 저하를 유발한다.

👑 갑질 (커널급 통제 방식)

4. Mutex

  • 커널 객체 기반 동기화.
  • 프로세스 간 동기화까지 가능함.
  • lock보다 무겁고 느림 (커널 모드 진입).
  • 소유권 개념이 있으며, 소유한 스레드만 해제 가능.
  • 데드락 위험이 큼, 꼭 try/finally 또는 using으로 보호.
Mutex mutex = new Mutex();
mutex.WaitOne(); // 잠금 획득
try
{
    // 임계 구역
}
finally
{
    mutex.ReleaseMutex(); // 잠금 해제
}

5. AutoResetEvent / ManualResetEvent

  • 스레드 간 이벤트 통신에 적합.
  • AutoResetEvent: 하나의 스레드만 깨움 (자동 초기화)
  • ManualResetEvent: 여러 스레드 깨움 가능 (수동 초기화 필요)
  • 커널 모드 동기화로서 성능은 낮지만 정밀한 제어 가능.
  • 주로 작업 완료 통보, 순차적 실행 보장에 사용됨.
AutoResetEvent autoEvent = new AutoResetEvent(false);

// 스레드1
autoEvent.WaitOne(); // 이벤트 기다림

// 스레드2
autoEvent.Set();     // 이벤트 발생

분류 표

분류 방식 설명
근성 Monitor (lock) 유저 모드 임계 구역 보호
  SpinLock 커널 진입 없이 반복 검사로 자원 점유
양보 Thread.Yield / Sleep CPU 점유권을 자발적으로 양보
갑질 Mutex 커널 모드, 프로세스 간 락, 무거움
  AutoResetEvent / ManualResetEvent 커널 이벤트, 스레드 간 통신 용이

  • 짧은 임계 구역에는 SpinLock이 더 낫고,
  • 장시간 대기가 필요한 경우엔 AutoResetEvent 또는 Mutex가 안전하다.
  • 게임 서버처럼 실시간성이 중요한 시스템에서는 유저 모드 동기화 → 선호
    다만, 상황에 따라 커널 객체도 필요하므로 선택 기준이 중요하다.

 

출처 : [C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버 강의 | Rookiss - 인프런

 

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버 강의 | Rookiss - 인프런

Rookiss | , MMORPG 개발에 필요한 모든 기술, C# + Unity로 Step By Step! 🕹️ [사진] 기초부터 끝판왕까지, MMORPG 개발하기 🎮  아무런 지식도 없다는 가정하에 누구나 부담없이 차근차근 수강할 수 있도

www.inflearn.com

 

댓글