2009-03-13 3 views
8

과도 함이 아닌가요? C# herehere에서 상호 제외 및 잠금에 대한 다른 게시물을 검색하고 발견했습니다.

예 :
우리 앱에는 여러 재 연결 스레드를 돌리는 기능이 있으며이 스레드 내부에는 Mutexlock을 사용합니다. lock이 코드 섹션에 대한 액세스를 차단하지 않고 connect이 다른 스레드에 의해 업데이트되지 않도록할까요?C#의 잠금 및 뮤텍스를 함께 사용해야합니까?

bool connect = false; 
Mutex reconnectMutex = new Mutex(false, "Reconnect_" + key); 

try 
{ 
    lock(site) 
    { 
     if(site.ContainsKey(key)) 
     { 
     siteInfo = (SiteInfo)site[key]; 
     if(reconnectMutex.WaitOne(100, true)) 
     { 
      connect = true; 
     } 
     } 
    } 

    if (connect) 
    { 
     // Process thread logic 
    } 
} 
catch 
{} 

reconnectMutex.ReleaseMutex(); 

추가 정보 : 이것은 ASP.NET WebService를 웹 가든에서 실행되지이다
.

답변

11

Mutex (이름이 있기 때문에)는 동일한 프로세스에서 동일한 프로세스의 모든 프로세스를 중지하지만 잠금은 동일한 프로세스의 다른 스레드 만 중지합니다. 그 코드 샘플에서 왜 두 가지 종류의 잠금이 필요한지 알 수 없습니다. 짧은 시간 동안 간단한 잠금을 유지하는 것이 좋습니다.하지만 훨씬 더 무거운 프로세스 간 뮤텍스는 아마도 더 긴 (중복되는) 기간 동안 잠겨 있습니다! 뮤텍스를 사용하는 것이 더 간단 할 것입니다. 아마도 프로세스 간 잠금이 실제로 필요한지 여부를 확인해야합니다.

그런데 catch {}은 그 시나리오에서 절대적으로 잘못된 것입니다. finally { /* release mutex */ }을 사용해야합니다. 그들은 매우 다릅니다. 캐치는 것보다 예외 훨씬 더 많은 종류를 삼킬 것이며, 또한 마지막으로 등 메모리 손상, 액세스 위반, 낮은 수준의 예외에 대한 응답으로 실행 핸들러 그래서 대신 중첩가 발생합니다

try 
{ 
    // something 
} 
catch 
{} 

// cleanup 

try 
{ 
    // something 
} 
finally 
{ 
    // cleanup 
} 

을 그리고 당신은 복구 할 수있는 특정 예외가있는 경우, 당신이 그들을 잡을 수있다 : 당신은해야

try 
{ 
    // something 
} 
catch (DatabaseConfigurationError x) 
{ 
    // tell the user to configure the database properly 
} 
finally 
{ 
    // cleanup 
} 
+0

따라서 기계 별 이름을 지정해야합니다. –

+0

좋은 점은, 첫 번째 문장에서 그 점을 분명히 밝혀 줬습니다. –

+0

catch 문을 제거하고 마지막 문으로 대체해야한다고 말하는 것입니까? –

3

"잠금은"다만 기본적으로 Montor.Enter/Exit에 대한 구문 설탕. 뮤텍스는 다중 프로세스 잠금입니다.

그들은 매우 다른 행동을합니다. 동일한 애플리케이션이나 메소드에서 둘 다 사용하는 것은 잘못된 것이 아닙니다. 서로 다른 것을 차단하도록 설계 되었기 때문입니다.

그러나 귀하의 경우에는 세마포 및 모니터를 살펴 보는 것이 더 나을 것 같습니다. 프로세스간에 잠글 필요가없는 것처럼 들리므로이 상황에서 더 나은 선택 일 수 있습니다.

1

정말 대답에 충분한 정보를 제공하지 않았습니다. Earwicker에서 이미 언급했듯이 뮤텍스를 사용하면 프로세스 간 동기화가 가능합니다. 따라서 동일한 응용 프로그램의 두 인스턴스가 실행중인 경우 액세스를 직렬화 할 수 있습니다. 예를 들어 외부 자원을 사용할 때이 작업을 수행 할 수 있습니다.

이제 사이트를 잠그면 동일한 프로세스에서 다른 스레드가 액세스하지 못하도록 사이트가 보호됩니다. 이것은 다른 메소드/스레드가 수행하는 작업에 따라 다를 수 있습니다. 이제 이것이 사이트가 잠겨있는 유일한 장소라면 예스살레스가 과잉이라고 생각할 것입니다.

2

Mutex는 프로세스간에 잠금을 설정하고 로컬 잠금 (Monitor)은 현재 프로세스가 소유 한 스레드 만 잠급니다. 그러나 ...

표시 한 코드는 심각한 버그가 있습니다.끝에서 무조건 Mutex를 해제하는 것처럼 보입니다 (즉, reconnectMutex.ReleaseMutex()). site.ContainsKey()true을 반환하는 경우에만 뮤텍스를 획득합니다.

site.ContainsKeyfalse을 반환하면 호출 스레드가 뮤텍스를 소유하지 않기 때문에 뮤텍스를 해제하면 ApplicationException을 반환합니다.

+0

고마워요. 게시 한 후에 그 버그를 발견했습니다. 왜 그 앱이 닫히는 지 알 수 없었습니다. 그것이 문제였습니다. –

관련 문제