[C# 서버] DeadLock

Yerin·2023년 9월 19일

C# 게임 서버

목록 보기
7/13

DeadLock이 발생하는 경우

아래와 같이 2개의 Lock이 존재하며,
2개의 쓰레드가 Lock에 접근하는 경우 DeadLock이 발생했다.

namespace SeverCore
{
    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 Test()
        {
            lock (_lock)
            {
                SessionManager.TestSession();
            }
        }
        public static void TestUser()
        {
            lock (_lock)
            {
            }
        }
    }

    class Program
    {
        static int number = 0;
        static object _obj = new object();

        static void Thread_1()
        {

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

        }


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

        static void Main(string[] args)
        {
            Task t1 = new Task(Thread_1);
            Task t2 = new Task(Thread_2);
            t1.Start();
            t2.Start();

            Task.WaitAll(t1, t2);

            Console.WriteLine(number);
        }
    }
}

이 상황을 어떻게 해결할까?

Monitor.TryEnter()

Monitor.TryEnter() 키워드를 이용해서 일정시간동안 lock을 획득하지 못했으면 포기하도록 할 수 있다.
하지만 이와 같은 경우 결국 lock 구조에 문제가 있다는 것이니 좋은 해결책은 아닐 수 있다.

Monitor.TryEnter();

Thread.Sleep()

Thread.Sleep 키워드를 이용해 해당 명령어들의 실행을 어긋나도록 만드는 것도 해결책이 될 수 있다.

static void Main(string[] args)
        {
            Task t1 = new Task(Thread_1);
            Task t2 = new Task(Thread_2);
            t1.Start();
            t2.Start();

            Thread.Sleep(100);

            Task.WaitAll(t1, t2);

            Console.WriteLine(number);
        }

하지만 보통은 crash가 난 다음에 고치는 경우가 흔하다.
DeadLock은 굉장히 까다롭기 때문에!

profile
재밌는 코딩 공부

0개의 댓글