VisualStudio/C++서버

[C#서버][개념] 임계영역과 데드락 해결방법

usingsystem 2022. 10. 26. 14:49
728x90

데드락

데드락이 일어나는 경우 서로간 참조할 때 서로의 락이 걸릴경우 아래소스와 같을 경우 데드락 발생.

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

        public static void TestSession()
        {
            lock (_locks)
            {
                UserManager.TestUser();
            }
        }
    }
    class UserManager
    {
        static object _locks = new object();

        public static void TestUser()
        {
            lock (_locks)
            {
                SessionManager.TestSession();
            }
        }
    }

    internal class Program
    {
        static int number = 0;
        static object _obj = new object();
        static void Thread_1()
        {
            for (int i = 0; i < 100000; i++)
            {
                SessionManager.TestSession();
            }
        }

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

        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);
        }
    }

데드락 해결방법 

1.  Monitor.TryEnter사용

Monitor.TryEnter(_locks, 1000)에서는 시간을 정해줄 수 있다. 정해진 시간안에 진입하지 않았을 때 로직을 만들어 사용할 수있다.

Monitor.TryEnter(_locks, 1000);
UserManager.TestUser();

 

2. Rock에 ID를 부여하여 사용(우선순위를 정하자)

 

 class FastLock 
    { 
       public int id; 
    }

    class SessionManager
    {
        FastLock I;
        static object _locks = new object();

        public static void TestSession()
        {
            Monitor.TryEnter(_locks, 1000);
                UserManager.TestUser();
        }
    }
    class UserManager
    {
        FastLock I;

        static object _locks = new object();

        public static void TestUser()
        {
            lock (_locks)
            {
                SessionManager.TestSession();
            }
        }
    }​

 

728x90