[게임 서버] 1.14 세마포어
카테고리: GameServer
태그: GameServer
이 글은 아래의 책을 자세히 정리한 후, 정리한 글을 GPT에게 요약을 요청하여 작성되었습니다.
게임 서버 프로그래밍 교과서, 배현직 저자
📦 1. 멀티스레딩
👉🏻 항목 14: 세마포어
Semaphore sema1;
void main() {
sema1 = new Semaphore(2);
}
void Thread1() {
sema1.Wait();
sema1.Release();
}
void Thread2() {
sema1.Wait();
sema1.Release();
}
void Thread3() {
sema1.Wait();
sema1.Release();
}
- 각 스레드는 세마포어에게 자원 액세스를 요청하고 대기한다.
- 세마포어는 최대 2개의 스레드만 액세스를 허락한다.
- 일을 마친 스레드는 세마포어에게 액세스가 끝났음을 통보한다.
- 대기하고 있는 스레드가 액세스를 허락받는다.
💻 윈도우에서의 세마포어 관련 함수
함수 | 설명 |
---|---|
CreateSemaphore |
세마포어 생성. 허락할 자원 개수도 이때 설정. |
WaitForSingleObject |
세마포어가 자원 액세스 요청 후, 대기 |
ReleaseSemaphore |
세마포어에 자원 액세스 끝났음을 통보 |
CloseHandle |
세마포어 파괴 |
※ 세마포어 자원 개수를 1로 설정하면 이벤트나 뮤텍스와 거의 비슷하게 동작한다.
📌 세마포어의 특징
- 세마포어는 상태 값을 가진다. 이 값은 0 이상의 정수다.
- 초기 값은 ‘최대 동시에 접근 가능한 스레드 수’다.
Wait()
호출 시 상태 값이 1 감소한다.Release()
호출 시 상태 값이 1 증가한다.- 상태 값이 0이면 추가 접근은 대기 상태로 들어간다.
✅ 세마포어 사용 예시
Queue queue;
Semaphore queueIsNotEmpty;
void Main()
{
// 초깃값이 0인 세마포어를 만든다.
queueIsNotEmpty = new Semaphore(0);
}
void Thread1()
{
while (true)
{
queueIsNotEmpty.Wait();
queue.PopFront();
}
}
void Thread2()
{
while (true)
{
queue.PushBack();
queueIsNotEmpty.Release();
}
}
이 예시는 큐에 항목이 들어오면 처리하는 소비자-생산자 구조를 세마포어로 구현한 것이다.
queueIsNotEmpty
세마포어는 큐의 항목 수와 동기화된다.- 소비자 스레드(Thread1)는 세마포어가 1 이상이 되길 기다린 뒤 항목을 꺼낸다.
- 생산자 스레드(Thread2)는 항목을 넣고 세마포어를 증가시킨다.
이벤트로 구현할 수도 있지만 이런 카운팅이 필요한 상황에서는,
세마포어가 훨씬 자연스럽고 구현이 깔끔하다.
댓글남기기