[C#] 잠금은 정확히 어떻게 작동합니까?

스레드로부터 안전하지 않은 객체를 사용하려면 다음과 같이 잠금으로 코드를 래핑합니다.

private static readonly Object obj = new Object();

lock (obj)
{
    // thread unsafe code
}

따라서 여러 스레드가 동일한 코드에 액세스하면 어떻게됩니까 (ASP.NET 웹 응용 프로그램에서 실행되고 있다고 가정합니다). 그들은 대기열에 있습니까? 그렇다면 얼마나 오래 기다 립니까?

잠금 사용으로 인한 성능 영향은 무엇입니까?



답변

lock문장은 C # 3.0에 의해 다음과 같이 번역됩니다.

var temp = obj;

Monitor.Enter(temp);

try
{
    // body
}
finally
{
    Monitor.Exit(temp);
}

C # 4.0에서는 이것이 변경 되었으며 이제 다음과 같이 생성됩니다.

bool lockWasTaken = false;
var temp = obj;
try
{
    Monitor.Enter(temp, ref lockWasTaken);
    // body
}
finally
{
    if (lockWasTaken)
    {
        Monitor.Exit(temp);
    }
}

당신은 무엇에 대한 자세한 정보를 찾을 수 있습니다 Monitor.Enter않습니다 여기를 . MSDN을 인용하려면 :

Enter매개 변수로 전달 된 오브젝트에서 모니터를 획득하는 데 사용하십시오 . 다른 스레드가 Enter
객체에서 실행했지만 해당를 아직 실행하지 않은 Exit경우 다른 스레드가 객체를 해제 할 때까지 현재 스레드가 차단됩니다. 동일한 스레드가 Enter차단없이 두 번 이상 호출하는 것이 합법적입니다
. 그러나 Exit객체를 기다리는 다른 스레드가 차단을 해제하기 전에 동일한 수의 호출 을
호출해야합니다.

Monitor.Enter방법은 무한정 기다릴 것입니다. 그것은 것입니다 하지 타임 아웃.


답변

생각보다 간단합니다.

Microsoft 에 따르면 : lock키워드는 한 스레드가 중요한 코드 섹션에 들어 가지 않고 다른 스레드가 중요한 섹션에 있도록합니다. 다른 스레드가 잠긴 코드를 입력하려고하면 객체가 해제 될 때까지 기다립니다.

lock키워드는 호출 Enter블록의 시작과 Exit블록의 끝에서. lock키워드는 실제로 Monitor백엔드에서 클래스를 처리합니다 .

예를 들면 다음과 같습니다.

private static readonly Object obj = new Object();

lock (obj)
{
    // critical section
}

위의 코드에서 스레드는 먼저 임계 구역으로 들어간 다음 잠 깁니다 obj. 다른 스레드가 들어 가려고 할 때 obj이미 첫 번째 스레드에 의해 잠긴 lock을 시도합니다 . 두 번째 스레드는 첫 번째 스레드가 해제 될 때까지 기다려야합니다 obj. 첫 번째 스레드가 떠나면 다른 스레드가 잠기고 obj중요한 섹션으로 들어갑니다.


답변

아니, 그들은 대기하지 않고, 자고있다.

양식의 잠금 문

lock (x) ... 

여기서 x는 참조 유형의 표현식입니다.

var temp = x;
System.Threading.Monitor.Enter(temp);
try { ... }
finally { System.Threading.Monitor.Exit(temp); }

당신은 그들이 서로 기다리고 있다는 것을 알아야하며, 하나의 스레드 만 블록을 잠그기 위해 들어가고 다른 스레드는 기다릴 것입니다 …

모니터는 .net으로 완전히 작성되었으므로 충분히 빠릅니다. 자세한 내용 은 리플렉터 가있는 모니터 클래스 를 참조하십시오.


답변

잠금은 다른 스레드가 잠금 블록에 포함 된 코드를 실행하지 못하도록 차단합니다. 스레드는 잠금 블록 내부의 스레드가 완료되고 잠금이 해제 될 때까지 기다려야합니다. 이것은 다중 스레드 환경에서 성능에 부정적인 영향을 미칩니다. 이를 수행해야하는 경우 잠금 블록 내의 코드가 매우 빠르게 처리 될 수 있는지 확인해야합니다. 데이터베이스 액세스 등과 같은 값 비싼 활동을 피해야합니다.


답변

성능 영향은 잠금 방식에 따라 다릅니다. http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/ 에서 좋은 최적화 목록을 찾을 수 있습니다 .

기본적으로 대기 코드를 잠자기 때문에 가능한 한 적게 잠그십시오. 잠금에 많은 계산이나 오래 지속되는 코드 (예 : 파일 업로드)가있는 경우 성능이 크게 저하됩니다.


답변

잠금 명령문 내의 파트는 하나의 스레드 만 실행할 수 있으므로 다른 모든 스레드는 잠금을 보유한 스레드가 완료 될 때까지 무기한 대기합니다. 이로 인해 소위 교착 상태가 발생할 수 있습니다.


답변

lock명령문은의 EnterExit메소드 호출로 변환됩니다 Monitor.

lock잠금 개체가 해제 될 때까지 문이 무기한 기다립니다.


댓글 달기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다