[게임 서버] 1.14 세마포어

업데이트:     Updated:

카테고리:

태그:

이 글은 아래의 책을 자세히 정리한 후, 정리한 글을 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();
}
  1. 각 스레드는 세마포어에게 자원 액세스를 요청하고 대기한다.
  2. 세마포어는 최대 2개의 스레드만 액세스를 허락한다.
  3. 일을 마친 스레드는 세마포어에게 액세스가 끝났음을 통보한다.
  4. 대기하고 있는 스레드가 액세스를 허락받는다.



💻 윈도우에서의 세마포어 관련 함수

함수 설명
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)는 항목을 넣고 세마포어를 증가시킨다.


이벤트로 구현할 수도 있지만 이런 카운팅이 필요한 상황에서는,
세마포어가 훨씬 자연스럽고 구현이 깔끔하다.

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

댓글남기기