[게임 서버] 1.13 이벤트

업데이트:     Updated:

카테고리:

태그:

이 글은 아래의 책을 자세히 정리한 후, 정리한 글을 GPT에게 요약을 요청하여 작성되었습니다.
게임 서버 프로그래밍 교과서, 배현직 저자

📦 1. 멀티스레딩

👉🏻 항목 13: 이벤트

📌 이벤트란?

잠자는 스레드를 깨우는 도구
스레드 간 소통을 위해 사용하며, 내부적으로 상태 값을 가짐

  • 🔁 Reset: 이벤트 없음 (상태 = 0)
  • Set: 이벤트 발생 (상태 = 1)



💻 윈도우에서의 이벤트 관련 함수

함수 설명
CreateEvent 이벤트 생성
CloseHandle 이벤트 파괴
WaitForSingleObject 이벤트 대기
SetEvent 이벤트에 신호 줌 (상태 1)



⚙️ 이벤트의 두 가지 모드

🔄 자동 이벤트 (Automatic Event)

  • 이벤트 상태 값이 1이 됨
  • 대기 중인 단 하나의 스레드만 깨움
  • 이후 상태가 자동으로 0으로 바뀜

🛠️ 수동 이벤트 (Manual Event)

  • 이벤트 상태 값이 1이 됨
  • 대기 중인 모든 스레드를 깨움
  • 이후 상태는 여전히 1을 유지
  • 상태를 0으로 바꾸려면 수동으로 Reset 필요



❗ 스레드 여러 개가 대기하는 상황

모드 행동
자동 이벤트 하나만
수동 이벤트 모두


✅ 수동 이벤트 예시

Event event1;

void Thread1() {
	event1.Wait();     // 신호 발생 대기
	event1.SetEvent(0); // 상태 값을 0으로
}

void Thread2() {
	event1.SetEvent(); // 이벤트에 신호 줌
}


❌ 수동 이벤트에서 모든 스레드를 깨우고 상태 값을 0으로 만들고 싶다면?

// 수동 이벤트
Event event1;

void Thread1() {
	event1.Wait();      // 신호 발생 대기
	event1.SetEvent(0); // 상태 값을 0으로
}

void Thread2() {
	event1.Wait();      // 신호 발생 대기
	event1.SetEvent(0); // 상태 값을 0으로
}

void Thread3() {
	event1.SetEvent();  // 이벤트에 신호를 줌
}
  • 이 코드는 잘못된 코드다.
  • 상태 값을 0으로 바꾸는 시점은 모든 스레드가 이벤트 대기에서 깨어난 후여야 한다.
  • 하지만 그 정확한 시점을 알 수 없다!
  • → ❌ 미정의 동작에 빠질 수 있음



🛠️ 해결책: PulseEvent 기능

이벤트 상태를 1로 바꾸고, 곧바로 0으로 되돌림

→ 이를 사용하면 대기중인 스레드를 한번만 깨울 수 있다.


✅ PulseEvent 예시

Event event1;

void Thread1() {
	event1.Wait(); // 신호 발생 대기
}

void Thread2() {
	event1.Wait(); // 신호 발생 대기
}

void Thread3() {
	event1.PulseEvent(); // 이벤트에 신호를 줌
}



🧐 정리

  • 이벤트는 스레드 간 동기화를 위한 신호 도구
  • 자동 이벤트: 하나만 깸, 상태는 자동으로 0
  • 수동 이벤트: 모두 깸, 상태는 수동으로 0
  • 모든 스레드가 깬 후 Reset을 수동으로 시도하는 건 위험 (미정의 동작 발생)
  • 이를 위해 PulseEvent를 활용하면 안전하게 동작 가능

GameServer 카테고리 내 다른 글 보러가기

댓글남기기