본문 바로가기
[2]SW Development Note/[2-2.2].NET CLR

[Thread Book #10] Monitor 생성자로 잠그기

by 오늘도 빛나는 너에게 2020. 7. 26.
728x90

[Thread Book #10]  Monitor 생성자로 잠그기

교착 상태 (DeadLock)라고 부르는 흔한 다른 멀티 스레드 오류를 보여준다.
교착 상태는 프로그램 작동을 멈추게 하는 원인이다.
이번예제의 첫부분은 교착상태를 회피할수있는 새로운  'Monitor' 생성자다.
그다음에는 교착 상태를 얻을때 이전에 설명했던 lock 키워드를 사용한다. 교착상태를 회피할수 생성자다.

class Program
       {
              static void Main(string[] args)
              {
                     object lock1 = new object();
                     object lock2 = new object();
                     new Thread(() => LockTooMuch(lock1, lock2)).Start();
                     lock (lock2)
                     {
                           Thread.Sleep(1000);
                           Console.WriteLine("Monitor.TryEnter를 사용하면 특정 시간 초과, 경과 한 후 false를 반환하여 멈출 수 없습니다.");
                           if (Monitor.TryEnter(lock1, TimeSpan.FromSeconds(5)))
                           {
                                  Console.WriteLine("보호된 리소스를 성공적으로 획득함");
                           }
                           else
                           {
                                  Console.WriteLine("리소스 수집 시간 초과!");
                           }
                     }
                     new Thread(() => LockTooMuch(lock1, lock2)).Start();
                     Console.WriteLine("----------------------------------");
                     lock (lock2)
                     {
                           Console.WriteLine("교착 상태가 될 거야!");
                           Thread.Sleep(1000);
                           lock (lock1)
                           {
                                  Console.WriteLine("보호된 리소스를 성공적으로 획득함");
                           }
                     }
              }
              static void LockTooMuch(object lock1, object lock2)
              {
                     lock (lock1)
                     {
                           Thread.Sleep(1000);
                           lock (lock2);
                     }
              }
       }


LockTooMuch 메소드부터 시작하자, 이 메소드에서 첫번째 객체를 잠근후 1초간 기다리다가 두 번째 객채를 잠근다.
그다음에는 다른 스레드에서 이 메소드를 시작한 후 두번째 객체를 Lock으로 잠근 다음에 메인 스레드의 첫 번째 객체에 대한 잠그기를 시도 한다.

이데모의 두번째 부분에서도 Lock 키워드를 동일하게 사용하며,교착 상태에 빠진다. 첫번째 스레드는 Lick1 객체를 붙잡고,Lock2객체가 풀리 때까지
기다린다. 메인 스레드는 Lock2 객체를 Lock으로 붙잡고,풀리게될 Lock1 객체를 기다리지만, 이런 상황에서도 결코 발생하지 않는다.

실제로 Lock 키워드는 Monitor 클래스 사용에 대한 구문적 치장 Syntactic sugar2 이다.
Lock이 있는 코드를 역어셈블 했다면 다음 코드 조각으로 변환됐음을 볼수 있다.


bool acuiredLock =false;
try
{
  Monitor.Enter(lockObject,ref acquieLock);
   //Lock 으로 보호된 자원에 접근하는 코드


}
finally
{
   if  (acquireLock)
    {
       Monitor.Exit (lockObject);
  }
}


따라서 타임아웃 파라미터를 받고,Lock으로 보호된 자원을 취득할 수 있기 전에 타임 아웃 파라미터가 경과되면
false를 반환하는 TryEntry 메소드를 갖는 Monitor 클래스를 직접 사용할수 있다.



출처 : C# 멀티스레드 프로그래밍 -유진 아가포노프 -  



Monitor.TryEnter 메서드 (System.Threading) | Microsoft Docs

지정된 개체의 단독 잠금을 가져오려고 했습니다.Attempts to acquire an exclusive lock on the specified object.






728x90

댓글