[C#] C #의 재진입 잠금

다음 코드로 인해 .NET에서 C #을 사용하여 교착 상태가 발생합니까?

 class MyClass
 {
    private object lockObj = new object();

    public void Foo()
    {
        lock(lockObj)
        {
             Bar();
        }
    }

    public void Bar()
    {
        lock(lockObj)
        {
          // Do something 
        }
    }
 }



답변

아니요, 같은 물건을 잠그는 동안은 아닙니다. 재귀 코드는 효과적으로 이미 잠금 을 가지고 있으므로 방해받지 않고 계속할 수 있습니다.

lock(object) {...}Monitor 클래스 를 사용하는 약어입니다 . 으로 마크가 지적 , Monitor재진입 그래서 객체에 잠금 시도를 반복, 현재의 thread가 이미 잠금이있는 잘 작동됩니다.

다른 물체를 잠그기 시작 하면주의해야합니다. 다음 사항에 특히주의하십시오.

  • 항상 동일한 시퀀스에서 주어진 수의 개체에 대한 잠금을 획득합니다.
  • 잠금 을 획득하는 방법 과 반대 순서로 항상 잠금을 해제하십시오 .

이러한 규칙 중 하나를 위반하면 어느 시점에서 교착 상태 문제가 발생할 수 있습니다.

다음은 .NET의 스레드 동기화를 설명하는 좋은 웹 페이지입니다. http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/

또한 한 번에 가능한 적은 수의 개체를 잠급니다. 가능하면 거친 잠금을 적용 하는 것이 좋습니다. 개체 그래프가 있고 해당 개체 그래프의 루트에 대한 잠금을 획득 할 수 있도록 코드를 작성할 수 있다면 그렇게하세요. 즉, 해당 루트 개체에 대해 하나의 잠금이 있으므로 잠금을 획득 / 해제하는 순서에 대해별로 걱정할 필요가 없습니다.

(참고로, 귀하의 예제는 기술적으로 재귀 적이 지 않습니다. 재귀 Bar()적이려면 일반적으로 반복의 일부로 자신을 호출해야합니다.)


답변

글쎄, Monitor재진입을 허용하므로 스스로 교착 상태를 유지할 수 없습니다 … 그래서 아니오 : 그렇게해서는 안됩니다.


답변

스레드가 이미 잠금을 보유하고있는 경우 자체적으로 차단되지 않습니다. .Net 프레임 워크가이를 보장합니다. 두 개의 스레드가 코드 경로에 관계없이 순서에 상관없이 동일한 두 개의 잠금을 획득하려고 시도하지 않는지 확인하기 만하면됩니다.

동일한 스레드가 동일한 잠금을 여러 번 획득 할 수 있지만 잠금을 획득 한 횟수와 동일한 횟수만큼 잠금을 해제해야합니다. 물론이 작업을 수행하기 위해 “lock”키워드를 사용하는 한 자동으로 발생합니다.


답변

아니요,이 코드에는 데드락이 없습니다. 정말로 교착 상태를 만들고 싶다면 가장 간단한 것은 최소한 2 개의 리소스가 필요합니다. 개와 뼈 시나리오를 고려하십시오. 1. 개는 1 개의 뼈를 완전히 제어 할 수 있으므로 다른 개는 기다려야합니다. 2. 2 개의 뼈를 가진 개 2 개는 각각 뼈를 잠그고 다른 뼈도 찾을 때 교착 상태를 생성하기 위해 최소한 필요합니다.

.. 등등 n 개의 개와 m 개의 뼈가 더 정교한 교착 상태를 유발합니다.


답변