KoreanFoodie's Study

[C++ 게임 서버] 1-10. Condition Variable (조건 변수) 본문

Game Dev/Game Server

[C++ 게임 서버] 1-10. Condition Variable (조건 변수)

GoldGiver 2023. 7. 14. 20:30

Rookiss 님의 '[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버' 를 들으며 배운 내용을 정리하고 있습니다. 관심이 있으신 분은 꼭 한 번 들어보시기를 추천합니다!

[C++ 게임 서버] 1-10. Condition Variable (조건 변수)

핵심 :

1. 조건 변수(Condition Variable) 은 유저 레벨 오브젝트로, 동일한 프로그램 내에서 접근 가능하다.

2. 조건 변수를 이용하면 하나의 쓰레드 혹은 모든 쓰레드에 시그널을 전달할 수 있다.

3. 조건 변수는 Lock 과 페어를 이루어 사용한다!

저번에 Handle 을 이용해 이벤트를 구현했던 것을 조금 발전시켜, 이번에는 condition variable 을 사용해볼 것이다.

사실 condition variable 은 Handle 을 사용하는 것보다 조금 더 우아한(?) 방식이며, 조건을 체크하여 락을 잡고 푸는 기능을 제공해 준다.

또한 condition variable 은 유저 레벨 오브젝트이므로, 동일한 프로그램 내에서만 공유하여 사용 가능하다! 😄

 

이전에 작업했던 Producer - Consumer 코드를 조금 고쳐보면...

// 참고 : 조건 변수는 커널 오브젝트가 아닌 User-Level 오브젝트이다.
condition_variable cv;

void Producer()
{
	for (int i = 0; i < 10000; ++i)
	{
		// 순서 :
		// 1. 락을 잡는다
		// 2. 데이터를 수정한다
		// 3. 락을 푼다
		// 4. 조건 변수에 노티를 준다
		{
			unique_lock<mutex> lock(m);
			q.push(i);
		}

		// condition variable 에 시그널 보내기. wait 중인 쓰레드 1개에게 신호를 보낸다.
		// notify_all() 을 하면 기다리는 모든 쓰레드에 신호를 보낸다.
		cv.notify_one();
	}
}

void Consumer()
{
	while (true)
	{
		// 순서 :
		// 1. 락을 잡는다.
		// 2. 조건 변수의 조건을 체크한다
		// 3. 조건이 만족되면 진행, 아니면 락 반납하고 대기 상태로 빠짐
		unique_lock<mutex> lock(m);

		cv.wait(lock, []() { return q.empty() == false; });

		{
			int data = q.front();
			q.pop();
			cout << "Data : " << data << endl;
		}
	}
}

코드를 보면 핸들을 이용하는 것과 거의 비슷하나, 차이점이 있다면 조건 변수는 락과 짝지어 사용한다는 것이다!

Comments