2012-02-09 2 views
3

두 프로세스를 동기화하기 위해 명명 된 시스템 뮤텍스를 사용하고 있습니다. MutexName로 명명 된 시스템 뮤텍스가 존재하지 않는 경우뮤텍스를 획득 할 때 경쟁 조건을 피하는 방법은 무엇입니까?

using System.Threading; 

public static bool AcquireMutex() 
{ 
    // Protect against double acquisitions 
    if (MyMutex != null) 
    { 
     throw new ApplicationException("Failed to acquire mutex"); 
    } 

    try 
    { 
     // See if a named system mutex has already been created - if it has, 
     // wait a short amount of time for its release. 
     MyMutex = Mutex.OpenExisting(MutexName); 
     if (!MyMutex.WaitOne(TimeSpan.FromSeconds(2), false)) 
     { 
      // MyMutex still being held 
      MyMutex = null; 
      return false; 
     } 
    } 
    catch 
    { 
     // MyMutex doesn't exist so create it 
     MyMutex = new Mutex(true, MutexName); 
    } 

    return true; 
} 

OpenExisting이 예외가 발생합니다, 그것을 만들 내 응용 프로그램을 허용 : 나는 현재 내 응용 프로그램 내에서 뮤텍스를 획득하고 방법이다.

그러나 여기에는 경쟁 조건이있는 것처럼 보입니다. OpenExisting이 throw되면 new Mutex을 호출하기 전에 작은 창이 나타나고 다른 응용 프로그램에서 뮤텍스를 획득했을 수 있습니다.

이 경쟁 조건을 피하고이 코드를보다 신뢰성있게 만드는 가장 좋은 방법은 무엇입니까?

동료가 자신의 코드 (다른 프로세스를 동기화해야 함)에서 Win32 Platform SDK의 CreateMutex을 사용하고 있다고 언급했습니다. 그러나 .NET Framework에서는 기본적으로 지원되지 않습니다. 그래서 나는 그것이 내 코드를위한 최상의 솔루션이라고 확신하지 못한다.

public static bool AcquireMutex() 
{ 
    // Protect against double acquisitions 
    if (MyMutex != null) 
    { 
     throw new ApplicationException("Failed to acquire mutex"); 
    } 

    bool createdNew; 
    MyMutex = new Mutex(true, MutexName, out createdNew); 
    if (createdNew) 
    { 
     // Mutex was created so ownership is guaranteed; no need to wait on it. 
     return true; 
    } 

    try 
    { 
     if (!MyMutex.WaitOne(TimeSpan.FromSeconds(2), false)) 
     { 
      MyMutex = null; 
      return false; 
     } 
    } 
    catch (AbandonedMutexException) 
    { 
     // Other application was aborted, which led to an abandoned mutex. 
     // This is fine, as we have still successfully acquired the mutex. 
    } 

    return true; 
} 
+0

예, 작동하지 않습니다. 프로세스 중 하나를 보스, 즉 보스로 만들어야합니다. 하나, 보통 첫 번째 하나를 선택하십시오. 다른 프로세스가 열 수 없다면 정말 잘못된 것이 있습니다. 기다려야 해. –

+0

@ 한스 - David Schwartz의 대답을 기반으로 변경했습니다. 업데이트 된 코드를보고 올바르게 표시되는지 알려주십시오. – LeopardSkinPillBoxHat

+0

AbandonedMutexException은 심각한 오류가있는 경우에만 throw됩니다. 위 코드 에서처럼 침묵하지 않을 것이지만 내 글로벌 예외 처리기가 추가 분석을 위해 기록하도록하십시오. 참조 : https://msdn.microsoft.com/en-us/library/system.threading.abandonedmutexexception(v=vs.110).aspx –

답변

4

특별히이 목적을 위해 설계 생성자있다 :


@ 데이비드 슈워츠의 답변에 따라 업데이트

, 여기 내 새로운 코드입니다.

createdNew
유형 : 다음 docs에서 선택 System.Boolean
때이 방법은 반환, 로컬 뮤텍스 (이름이 null의 경우, 또는 즉, 생성 된 경우 true 인 부울을 포함 빈 문자열) 또는 지정된 명명 된 시스템 뮤텍스가 작성된 경우; 지정된 네임드 시스템 뮤텍스가 이미 존재하면 false. 이 매개 변수는 초기화되지 않은 상태로 전달됩니다.

+0

답변 주셔서 감사합니다 - 원래 질문에서 내 업데이트 된 코드를 참조하십시오. 올바른지 알고 싶으면 알려주세요. – LeopardSkinPillBoxHat

관련 문제