2011-09-30 2 views
1

코드의 동기화 블록)에서 호출 하였다개체 동기화 방법은 다음 코드 Mutex.ReleaseMutex에 ("코드의 동기화 블록에서 호출 된 객체 동기화 방법"I 메시지와 생산 예외가 나타날

Mutex Mutex 
{ 
    get { return mutex ?? (mutex = new Mutex(false, mutexName)); } 
} 
[NonSerialized] 
Mutex mutex; 

public void Log(/*...*/) 
{ 
    Mutex.WaitOne(); 
    try 
    { 
     /*...*/ 
    } 
    finally 
    { 
     Mutex.ReleaseMutex(); 
    } 
} 

서로 다른 mutextName을 가진 뮤텍스를 사용할 수있는 여러 프로세스가있을 수 있습니다. 그리고 아직도 그 예외가 어떻게 일어날 지 모르겠습니다.

+0

실제로 의심되는 있지만 단일 프로세스 내에서 일부 경쟁 조건의 Mutex.WaitOne() 및 Mutex.ReleaseMutext() bacause 다른 뮤텍스 인스턴스 때문에 수도 있습니다 용의자. –

+1

뮤텍스를 만드는 것은 처음부터 스레드 안전하지 않습니다. 결국 하나 이상의 뮤텍스가 생길 수 있습니다. – vcsjones

+1

예, 추가 호출에 대한 호출이 이루어집니다. –

답변

7

이 코드 :

Mutex Mutex 
{ 
    get { return mutex ?? (mutex = new Mutex(false, mutexName)); } 
} 

스레드로부터 안전하지 않습니다, 하나 이상의 뮤텍스가 생성받을 수 있습니다. 가장 좋은 시간을 사용하여 다음 예제를 살펴 보겠습니다.

 
Thread A  | Thread B 
------------------------------------- 
Enters 
Is Null? (yes) Enters 
Create Mutex  Is Null? (yes) <- Thread A hasn't assigned it yet. 
Assign mutex  Create Mutex 
Use Mutex  Assign mutex <- Oops! We just overwrote the mutex thread A created! 
Release Mutex <- Oops! We are trying to release the mutex Thread B created without owning it! 

그 그림은 쓰레기가 아니길 바랍니다.

클래스를 사용하면 뮤텍스를 사용하여 실제로 초기화하려는 경우 지연 초기화를 수행하는 스레드로부터 안전한 방법입니다.

private Lazy<Mutex> _lazyMutex = new Lazy<Mutex>(() => new Mutex(false, "MyMutex")); 
Mutex Mutex 
{ 
    get { return _lazyMutex.Value; } 
} 

왜 뮤텍스를 게으른 초기화하려고합니까? 어떻게 그걸 버리는거야?

+0

유지 물체를 배치 할 때 뮤텍스가 배치됩니다. –