답변:
lock
실제 클래스 나 객체가 아닌 컴파일러 키워드입니다. Monitor
클래스 의 기능을 둘러싼 래퍼 이며 Monitor
일반적인 경우에 더 쉽게 작업 할 수 있도록 설계되었습니다 .
Darin이 말했듯 이 Monitor
(및 lock
키워드)는로 제한됩니다 AppDomain
. 주로 "잠금"을 관리하고 메모리 카드의 ID를 유지하려면 메모리 주소 (인스턴스화 된 객체 형태)에 대한 참조가 필요하기 때문에Monitor
은 Mutex
, 다른 한편으로는, 운영 체제 구조체 주위 닷넷 래퍼이며, 문자열하여, 시스템 전체의 동기화에 사용될 수 데이터 의 식별자 (데이터 대신에 포인터). 완전히 다른 두 개의 메모리 주소에서 두 개의 문자열을 참조하지만 동일한 데이터를 갖는 두 개의 뮤텍스 는 실제로 동일한 운영 체제 뮤텍스를 사용합니다.
A Mutex
는 프로세스 로컬 이거나 시스템 전체 일 수 있습니다. MSDN :
뮤텍스는 이름이없는 로컬 뮤텍스와 시스템 뮤텍스라는 두 가지 유형이 있습니다. 로컬 뮤텍스는 프로세스 내에서만 존재합니다.
또한 터미널 서비스가있는 시스템에서 시스템 전체 뮤텍스를 사용할 때는 같은 페이지에 자세히 설명되어있는 특별한주의가 필요합니다.
사이의 차이점 중 하나 Mutex
와 lock
즉 Mutex
활용 커널 수준의 구조를 동기화가 항상 최소한의 사용자 공간 커널 공간의 전환이 필요합니다, 그래서.
lock
-그것은 실제로 Monitor
클래스에 대한 지름길입니다. 반면에 커널 리소스 할당과 커널 코드로의 전환을 피하려고 시도합니다 (따라서 더 빠르며 빠릅니다)-비슷한 WinAPI 구조를 찾아야한다면 그렇게 될 것 CriticalSection
입니다.
다른 차이점은 다른 사람들이 지적한 것입니다. 프로세스 에서 명명 된 이름을 Mutex
사용할 수 있습니다.
특별한 요구가 있거나 프로세스 간 동기화가 필요한 경우가 아니라면 lock
(일명 Monitor
) 을 고수하는 것이 좋습니다.
포기 처리 방법 등과 같은 몇 가지 "사소한"차이점이 있습니다.
.NET 4.0 등 의 새로운 내용 ReaderWriterLock
과 ReaderWriterLockSlim
3.5에서 같은 내용을 말할 수 있습니다 . 후자의 클래스는 시스템 전체의 동기화 프리미티브로 사용할 수 없지만, "의미 한"의미는 아닙니다. 더 빠르고 자원 친화적 인Semaphore
SemaphoreSlim
xxSlim
Mutex를 사용하여 동일한 컴퓨터에서 이미 실행중인 응용 프로그램의 복사본이 있는지 확인합니다.
bool firstInstance;
Mutex mutex = new Mutex(false, @"Local\DASHBOARD_MAIN_APPLICATION", out firstInstance);
if (!firstInstance)
{
//another copy of this application running
}
else
{
//run main application loop here.
}
// Refer to the mutex down here so garbage collection doesn't chuck it out.
GC.KeepAlive(mutex);
이미 많은 말을했지만 간단하게하기 위해 다음과 같이하겠습니다.
자물쇠 > 사용하기 간단하고 모니터의 랩퍼는 AppDomain의 스레드를 잠급니다.
명명되지 않은 뮤텍스 -> 잠금 범위가 더 많고 프로세스의 AppDomain에 걸쳐 있다는 점을 제외하면 잠금과 유사합니다.
명명 된 뮤텍스 -> 잠금 범위는 명명되지 않은 뮤텍스 그 이상이며 운영 체제의 여러 프로세스에 걸쳐 있습니다.
이제 옵션이 있으므로 귀하의 경우에 가장 적합한 옵션을 선택해야합니다.
답변에 언급되지 않은 사소한 차이는 거의 없습니다.
잠금을 사용하는 경우 잠금 블록 내부에서 예외가 발생하면 잠금이 해제 되도록 할 수 있습니다 .
후드 아래에있는 잠금 사용의 모니터 및 구현 때문 이 방법을 :
object __lockObj = x;
bool __lockWasTaken = false;
try
{
System.Threading.Monitor.Enter(__lockObj, ref __lockWasTaken);
// Your code...
}
finally
{
if (__lockWasTaken) System.Threading.Monitor.Exit(__lockObj);
}
따라서 어떤 경우에도 잠금이 해제되므로 수동으로 해제 할 필요가 없습니다 (뮤텍스와 마찬가지로).
잠금의 경우 일반적으로 개인 객체 를 사용 하여 잠그고 사용해야합니다 .
이것은 여러 가지 이유로 수행됩니다. (자세한 정보 : 이 답변 및 공식 문서 참조 ).
따라서 잠금의 경우 외부에서 잠긴 오브젝트에 액세스 할 수 없으며 (실수로) 손상을 입을 수 있습니다.
그러나 Mutex의 경우 공용으로 표시되고 어디에서나 사용되는 Mutex를 갖는 것이 일반적이므로 가능합니다.