문제
이것은 과잉이 아니고 필요한 것 중 하나 일뿐입니까? C#의 상호 배제 및 잠금에 대한 다른 게시물을 검색하고 찾았습니다. 여기 그리고 여기.
예시:
우리의 앱에는 여러 번의 연결 스레드를 회전시키는 기능이 있으며이 스레드 내부에는 다음을 사용합니다. Mutex
그리고 a lock
. 그렇지 않을 것입니다 lock
이 코드 섹션에 대한 액세스를 차단하고 방지하십시오 connect
다른 스레드에서 업데이트되는 것입니까?
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 웹 서비스에 있습니다.
해결책
그 MUTEX (이름이 있기 때문에)는 동일한 기계의 프로세스에도 액세스하는 프로세스를 중지하는 반면, 잠금은 동일한 프로세스에서 다른 스레드 만 중지합니다. 그 코드 샘플에서 왜 두 종류의 잠금이 필요한지 알 수 없습니다. 짧은 시간 동안 간단한 자물쇠를 잡는 것이 좋은 관행 인 것 같습니다. 그러나 훨씬 더 무거운 간호가 Mutx는 아마도 더 오래 (겹치는) 기간 동안 잠겨 있습니다! 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
}
다른 팁
"잠금"은 기본적으로 Montor.enter/Exit의 구문 설탕입니다. Mutex는 다중 프로세스 잠금 장치입니다.
그들은 매우 다른 행동을 가지고 있습니다. 다른 것을 차단하도록 설계되었으므로 동일한 응용 프로그램이나 방법 모두에서 모두 사용하는 데 아무런 문제가 없습니다.
그러나 귀하의 경우, 나는 당신이 세마포어와 모니터를 조사하는 것이 더 나을 것이라고 생각합니다. 프로세스를 가로 질러 고정 해야하는 것처럼 들리지 않으므로이 상황에서 더 나은 선택 일 것입니다.
다른 사람들이 지적한 바와 같이, Mutex는 프로세스를 가로 지르고 로컬 잠금 (모니터)은 현재 프로세스가 소유 한 스레드 만 잠금합니다. 하지만 ...
당신이 보여준 코드에는 꽤 심각한 버그가 있습니다. 끝에 무조건 뮤트를 공개하는 것 같습니다 (즉 reconnectMutex.ReleaseMutex()
), 그러나 뮤텍스는 다음에만 취득됩니다 site.ContainsKey()
보고 true
.
그래서 만약 site.ContainsKey
보고 false
, 그런 다음 뮤텍스를 풀어주는 것이 던질 것입니다 ApplicationException
호출 스레드는 뮤텍스를 소유하지 않기 때문입니다.
당신은 정말로 이것에 답할 수있는 충분한 정보를 제공하지 않았습니다. Earwicker가 이미 언급했듯이 Mutex를 사용하면 동기화 accross 프로세스를 가질 수 있습니다. 따라서 동일한 앱 실행중인 두 인스턴스가 있으면 액세스를 직렬화 할 수 있습니다. 예를 들어 외부 리소스를 사용할 때이 작업을 수행 할 수 있습니다.
이제 사이트에서 동일한 프로세스에서 다른 스레드에 의한 사이트에 대한 사이트를 보호합니다. 이것은 다른 방법 / 스레드가 수행하는 일에 따라 Nessecary 일 수 있습니다. 이제 이것이 그 사이트가 잠겨있는 유일한 곳이라면 그렇습니다. 나는 그것이 과잉이라고 생각할 것입니다.