lock과 Mutex의 차이점은 무엇입니까? 왜 서로 바꿔 사용할 수 없습니까?
답변
답변
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에 걸쳐 있다는 점을 제외하면 잠금과 유사합니다.
명명 된 뮤텍스 -> 잠금 범위는 명명되지 않은 뮤텍스 그 이상이며 운영 체제의 여러 프로세스에 걸쳐 있습니다.
이제 옵션이 있으므로 귀하의 경우에 가장 적합한 옵션을 선택해야합니다.
답변
뮤텍스는 교차 프로세스이며 하나 이상의 응용 프로그램 인스턴스를 실행하지 않는 전형적인 예가 있습니다.
두 번째 예는 파일이 있고 동일한 파일에 액세스하기 위해 다른 프로세스를 원하지 않는다고 말하면 Mutex를 구현할 수 있지만 Mutex는 운영 체제 전체에서 두 원격 프로세스 사이에서 사용할 수 없다는 점을 기억하십시오.
잠금은 코드의 섹션을 보호하는 가장 간단한 방법이며 appdomain에 따라 다릅니다.보다 통제 된 동기화를 원할 경우 잠금을 Moniters로 바꿀 수 있습니다.
답변
답변에 언급되지 않은 사소한 차이는 거의 없습니다.
-
잠금을 사용하는 경우 잠금 블록 내부에서 예외가 발생하면 잠금이 해제 되도록 할 수 있습니다 .
후드 아래에있는 잠금 사용의 모니터 및 구현 때문 이 방법을 :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를 갖는 것이 일반적이므로 가능합니다.