2009-06-26 3 views
9

교착 상태 문제를 디버깅 중이며 호출 스택은 스레드가 일부 이벤트를 기다리고 있음을 보여줍니다.크리티컬 섹션 부정적인 락 카운트

코드는 동기화 기본 요소로 임계 구역을 사용합니다. 여기에 몇 가지 문제가 있다고 생각합니다. 또한 디버거가 다른 스레드가 소유 한 중요 섹션을 가리키고 있지만 잠금 개수는 -2입니다. 내 이해에 따라 잠금 개수> 0은 중요 섹션이 하나 이상의 스레드에 의해 잠겨 있음을 의미합니다.

그래서 교착 상태의 범인이 될 수있는 오른쪽 중요한 부분을 볼 가능성이 있습니다.

중요한 섹션의 음수 잠금 개수는 어떤 시나리오에서 발생할 수 있습니까?

+0

레이몬드 첸 (Raymond Chen)은 CS를 입력하는 것보다 더 많은 시간을 남겨 두었을 때의 결과에 관한 글을 방금 작성했습니다. 그리고 처음 세 댓글은 읽을만한 가치가 있습니다 ... http://blogs.msdn.com/oldnewthing/archive/2009/06/19/9777996.aspx – eran

답변

5

MFC에서 CCriticalSection 클래스에 대해 설명한다고 가정합니다. 나는 당신이 중요한 부분을 제대로보고 있다고 생각합니다. 나는 Lock() 함수에 대한 호출 수가 Unlock() 호출의 수보다 적은 경우 임계 섹션의 잠금 횟수가 음수가 될 수 있음을 발견했습니다. 이 문제는 일반적으로 다음 코드 유형에서 발생합니다.

void f() 
{ 
    CSingleLock lock(&m_synchronizer, TRUE); 
    //Some logic here 
    m_synchronizer.Unlock(); 
} 

언뜻보기에이 코드는 완벽하게 안전합니다. 그러나 CSingleicalLock의 Unlock() 메서드 대신 직접 CCriticalSection의 Unlock() 메서드를 사용하고 있습니다. 이제 함수가 종료되면 소멸자의 CSingleLock이 다시 임계 영역의 Unlock()을 호출하고 잠금 개수가 음수가됩니다. 이 후 응용 프로그램이 나쁜 모양과 이상한 일들이 발생하기 시작합니다. MFC 임계 영역을 사용하는 경우이 유형의 문제를 확인하십시오.

+0

LockCount는 사용중인 Windows의 버전에 따라 다릅니다. http : //msdn.microsoft.com/en-us/library/ff541979.aspx – hfrmobile

23

주의 : Windows Server 2003 (클라이언트 OS this is Vista and newer)부터 LockCount의 의미가 변경되고 -2는 완전히 정상적인 값으로, 스레드가 대기없이 중요한 섹션에 들어 왔을 때 다른 스레드가 기다리지 않을 때 일반적으로 나타납니다 연사. Displaying a Critical Section 참조 : 다음과 같이

마이크로 소프트에서 윈도우 서버 2003 서비스 팩 1 및 이후 버전의 Windows가의 LockCount 필드는 구문 분석 :

  • 가장 낮은 비트는 잠금 상태를 보여줍니다. 이 비트가 0이면 임계 구역이 잠겨 있습니다. 1이면 임계 영역이 잠기지 않습니다.
  • 다음 비트는 스레드가이 잠금에 대해 깨어 났는지 여부를 나타냅니다. 이 비트가 0의 경우,이 락용 thread가 깨우쳐지고 있습니다. 1이면 아무 스레드도 깨우지 못했습니다.
  • 나머지 비트는 잠금을 대기중인 스레드 수의 1의 보수입니다.
+3

멋진 정보 다른 곳에서는 본 적이 없습니다. 중요한 부분에서 이상한 행동을 해결하도록 도와주었습니다. –

+2

@와 mistiano 님의 댓글이 같습니다. 나는 Microsoft가 LockCount가 Server 2003 및 그 이상의 버전에서 작동하는 방식을 변경했다는 것을 몰랐습니다. 링크가 매우 유용했습니다! –