2010-02-10 3 views
3

이것은 이론적 인 질문입니다. 나는 해결할 실제 문제가 없으며 단지이 방식의 배경에 대한 추론을 이해하고자합니다.소유자 스레드가 종료되면 ReaderWriterLock이 자동으로 릴리스/종료되지 않는 이유는 무엇입니까?

스레드가 생략되어 ReaderWriterLock을 종료하면 다른 스레드가 원래 스레드가 종료 된 후에도 잠금을 획득하지 못한다는 것을 발견했습니다. ReaderWriterLock이 잠금을 소유 한 스레드가 종료 되 자마자 대기중인 스레드에 잠금을 부여하지 않는 데는 좋은 이유가 있습니까?

다음은이 문제를 보여주는 테스트 사례입니다.

static void Main(string[] args) 
    { 
     ReaderWriterLockSlim readerWriterLock = new ReaderWriterLockSlim(); 

     Thread t1 = new Thread((a) => 
     { 
      readerWriterLock.EnterReadLock(); 

      // this thread omits to Exit the lock.... 
     }); 

     Thread t2 = new Thread((a) => 
     { 
      readerWriterLock.EnterWriteLock(); 
     }); 

     t1.Start(); 
     t2.Start(); 

     // wait for all threads to finish 
     t1.Join(); 
     t2.Join(); 
    } 

답변

3

간단한 대답 : 잠금 스레드가 비싸지 않으면 서 작성자 스레드가 판독기 스레드가 종료되었음을 쉽게 알 수 없습니다.

잠금은 일반적으로 메모리에 값으로 구현되므로 잠금 해제를 얻으려면이 값을 변경해야합니다. 스레드가 잠금을 획득하기 위해 값을 설정하면 충돌이 발생하여 다른 잠금을 획득 할 수있는 유일한 방법은 죽은 스레드를 폴링하고 최근에 획득 한 잠금 목록을보고 정리하는 백그라운드 스레드가있는 경우입니다.

비싸고 배관이 많이 필요하다는 것 외에도, 스레드가 충돌하기 전에 스레드가 얼마나 멀리 있는지 정확히 알지 못하기 때문에 잠재적으로 안전하지 않습니다.

+0

크래시 된 스레드의 컨텍스트에서 잠금 된 리소스가 깨끗한 상태에 있다고 가정하면 위험 할 수 있습니다. 그러나 정상적인 스레드 종료의 맥락에서, 나는 그러한 가정이 안전하다고 생각한다. 성능과 관련하여 두 가지 구현을 제공 할 수 있습니다. 즉, 현재 구현 된 구현과 자동 출시를 구현하는 느리지 만 더 똑똑한 구현입니다. 어쨌든, 당신의 대답을 고맙습니다, 나는 당신이 설명했던 것이 참으로 그렇게 된 이유라고 생각합니다. – Sylvain

+1

Re : 정상적인 스레드 종료, 일부 범위를 벗어날 때 잠금이 해제되도록하는 잠금에 RAII 패턴을 사용할 것을 고려할 수 있습니다. C#에서는 _lock_ 키워드 (일반 잠금) 또는 _try/finally_ 블록 (ReaderWriterLock 용)을 사용하여 범위 종료시 잠금이 해제되도록 할 수 있습니다. 다시 말하지만 스레드가 충돌하거나 더 낮은 수준의 스레드 종료 함수를 호출 한 경우에도 도움이되지 않지만 일부 복잡한 코드 경로에서 잠금을 해제하지 않은 프로그래밍 오류로 인해 교착 상태가 발생할 위험을 줄일 수 있습니다. . – 0xfe

0

잠금 장치가 독점적으로 보유하고있는 스레드의 ID를 저장하는 것이 그리 어렵지 않을 것입니다. 잠금 코드는 차단 된 동안 주기적으로 검사하여 해당 스레드를 차단하고있는 스레드가 모두 살아 있는지 확인합니다. 가장 큰 문제점은 스레드가 잠금에 의해 보호되는 엔티티가 적법한 상태이거나 유효하지 않은 순간을 나타내는 순간에 표준 방법이 없다는 것입니다. 보호 된 엔티티가 유효하지 않은 상태에서 잠금을 보유하고있는 스레드가 죽는 경우, 해당 엔티티에 대한 액세스는 손상을 처리하는 방법을 알고있는 일부 코드가 그렇게 할 때까지 또는 금지되어야합니다.

관련 문제