KoreanFoodie's Study

[C++ 게임 서버] 1-5. DeadLock 의 개념과 기초 (+ std::lock) 본문

Game Dev/Game Server

[C++ 게임 서버] 1-5. DeadLock 의 개념과 기초 (+ std::lock)

GoldGiver 2023. 7. 10. 17:51

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

[C++ 게임 서버] 1-5. DeadLock 의 개념과 기초 (+ std::lock)

핵심 :

1. DeadLock 상황은, 여러 쓰레드들이 Lock 을 서로 잡고 있어 풀거나 새로 잡지 못하는 교착 상태를 의미한다.

2. DeadLock 상황은 Lock 을 잡는 순서를 잘 조절하거나, 적절한 Lock 을 사용하여 회피할 수 있다.

3. std::lock 은 여러 개의 Lock 을 DeadLock 없이 한꺼번에 잡을 수 있도록 도와준다.

다음과 같이, Lock 이 2개 존재하고 연산을 위해 Lock 2 개를 전부 잡아야 한다고 가정하자.

int sum = 0;

mutex mutexAdd;
mutex mutexSub;

void Add()
{
	for (int i = 0; i < 1000; ++i)
	{
		mutexAdd.lock();
		mutexSub.lock();

		++sum;

		mutexAdd.unlock();
		mutexSub.unlock();
	}
}

void Sub()
{
	for (int i = 0; i < 1000; ++i)
	{
		mutexSub.lock();
		mutexAdd.lock();

		--sum;

		mutexSub.unlock();
		mutexAdd.unlock();
	}
}

int main()
{
	thread t1(Add);
	thread t2(Sub);

	t1.join();
	t2.join();

	cout << "sum : " << sum << endl;
}

위의 상황에서, 쓰레드 t1 과 t2 가 각각 락을 잡는 과정에서 mutexAdd 와 mutexSub 가 동시에 잡혀 서로 아무것도 하지 못하는 상황이 생길 수 있는데, 이런 상황을 DeadLock 이라고 한다.

 

위처럼 간단한 상황의 경우에는, Lock 을 잡는 순서를 동일하게 유지 시켜 주어 해결할 수도 있지만...

// Add 다음에 Sub 를 잡도록 순서를 강제한다.
mutexAdd.lock();
mutexSub.lock();

현실적으로는 순서만으로 DeadLock 문제를 해결하긴 어렵다.

따라서 이런 문제를 해결하기 위해, 앞으로 Lock 을 구현하는 다양한 방법을 알아볼 것이다!

 

추가적으로, 이전에 배운 unique_lock 의 활용 예시를 하나 더 보자.

mutex m1, m2;

// Lock 여러개를 한번에 잡는다. 언어 자체적으로 deadlock 이 일어나지 않도록 Lock 을 잡음
std::lock(m1, m2);

// Lock 을 잡지는 않는다. 다만 Scope 를 나갈 때 Lock 을 풀어주어야 함을 알린다.
std::unique_lock<std::mutex> u1(m1, std::adopt_lock);
std::unique_lock<std::mutex> u2(m2, std::adopt_lock);

위 처럼, adopt_lock 옵션을 활용하면 LockGuard 를 유용하게 사용할 수 있다!

다만 일반적으로 위처럼 Lock 을 여러 개 잡도록 구현하지는 않을 것이다 😅

 

참고로, std::lock 의 내부 구현은 아래와 같이 생겼다 😎 :

_EXPORT_STD template <class _Lock0, class _Lock1, class... _LockN>
void lock(_Lock0& _Lk0, _Lock1& _Lk1, _LockN&... _LkN) { // lock multiple locks, without deadlock
    _Lock_nonmember1(_Lk0, _Lk1, _LkN...);
}
Comments