KoreanFoodie's Study
[C++ 게임 서버] 1-5. DeadLock 의 개념과 기초 (+ std::lock) 본문
[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...);
}
'Game Dev > Game Server' 카테고리의 다른 글
[C++ 게임 서버] 1-7. SpinLock 개념과 구현 (0) | 2023.07.11 |
---|---|
[C++ 게임 서버] 1-6. Lock 구현 이론 (0) | 2023.07.11 |
[C++ 게임 서버] 1-4. Lock 기초 (lock_guard, unique_lock) (0) | 2023.07.10 |
[C++ 게임 서버] 1-3. atomic (원자적) 변수와 연산 (0) | 2023.07.10 |
[C++ 게임 서버] 1-2. 쓰레드 생성 (0) | 2023.07.07 |
Comments