C#/네트워크

[c#][서버] 데드락

goliot 2024. 6. 2. 19:17
반응형

자물쇠가 여러 개인 경우

  • 두 사람이 한 화장실을 쓰려 함
  • 그런데 들어가려면 열쇠 두 개가 필요
  • 각자 자물쇠 한 개 씩 들고 있으면서 다른 자물쇠를 기다린다면?
    • 서로 다음 자물쇠를 기다리며 못들어가는 상황데드락 해결 방법
  • 규칙을 정한다
    • 무조건 위쪽 자물쇠부터 잠그고
    • 위쪽을 잠근 사람이 아래쪽도 가져가자

코드 예시

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();
      }
  }
}  
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);
  }
}
  • 서로 대기가 사이클이 되어 데드락이 발생
  • 이렇게 되면 Task.WaitAll에서 하염없이 대기중인 상태가 된다.

추가

  • t1, t2의 실행 사이에 시간 조금만 부여해 주면 데드락이 발생하지 않는다.
  • 데드락은 굉장히 까다롭고 예상하기 어렵다
    • 예외처리를 하기보다는, 발생을 시키고, 콜스택을 추적해서 고치는 방향으로 처리하자
반응형

'C# > 네트워크' 카테고리의 다른 글

[c#][서버] ReaderWriterLock  (0) 2024.06.03
[c#][서버] Lock 구현 이론  (0) 2024.06.02
[C#][서버] Lock 기초  (0) 2024.06.02
[C#][서버] Interlocked  (0) 2024.06.01
[C#][서버] 메모리 배리어  (0) 2024.06.01