1 분 소요

이 글은 Rookiss님의 [C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버를 보고 헷갈리는 부분 위주로 정리한 글입니다. 틀리거나 부족한 부분이 있을 수 있습니다.

DeadLock

멀티 쓰레드 환경에서 작업의 원자성을 보장하기 위해서 lock이라는 기능을 사용하였다.
이때 lock을 사용한 설계가 잘못된다면 DeadLock 상황에 빠질 수 있다.

DeadLock이란 두 개 이상의 쓰레드가 서로의 작업이 끝나기를 영원히 기다리는 상태이다.

DeadLock에 빠지는 코드 예시

다음은 DeadLock 간단한 예시이다.

두 개의 클래스 SessionManager와 UserManager가 있고, 두 클래스 모두 동일한 구성의 함수를 가지고 있다.
두 쓰레드 환경에서 각각의 클래스의 Test함수를 실행할 때 두 Test함수는 두 클래스 모두의 _lock을 요구한다.
Thread_1과 Thread_2가 실행되어 동시에 각각 SessionManager의 _lock과 UserManager의 _lock을 점유한다고 했을 때, 서로가 _lock을 점유하지만 또한 서로가 서로의 _lock도 필요로 하기에 무한히 서로를 기다리는 DeadLock상태에 빠지게 된다.

class SessionManager
{
    static object _lock = new object();

    public static void TestSession()
    {
        lock (_lock) 
        {
            
        }
    }
    public static void Test()
    {
        lock (_lock)
        {
            UserManager.TestUser();
        }
    }
}

class UserManager
{
    static object _lock = new object();

    public static void TestUser()
    {
        lock (_lock) 
        {

        }
    }
    public static void Test()
    {
        lock (_lock)
        {
            SessionManager.TestSession();
        }
    }
}

// 실행되는 쓰레드
static void Thread_1()
{
    for (int i = 0; i < 10000; i++)
    {
        UserManager.Test();
    }
}

static void Thread_2()
{
    for (int i = 0; i < 10000; i++)
    {
        SessionManager.Test();
    }
}

댓글남기기