[게임 서버] 1.13 이벤트
카테고리: GameServer
태그: GameServer
이 글은 아래의 책을 자세히 정리한 후, 정리한 글을 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
를 활용하면 안전하게 동작 가능
댓글남기기