Ответ
Mutex (взаимное исключение) может синхронизировать потоки из разных процессов, потому что это объект уровня операционной системы, а не среды выполнения (CLR).
Ключевые отличия от lock/Monitor:
lock(Monitor): Работает только в пределах одного процесса и домена приложения (AppDomain), используя память кучи CLR.Mutex: Создается в глобальном пространстве имен ядра ОС (например, в Windows). Разные процессы могут открыть хэндл одного и того же именованного объекта ядра.
Как это работает:
- При создании именованного
MutexОС регистрирует его в своем внутреннем пространстве имен (например,Global\MyAppMutex). - Любой процесс, знающий это имя, может открыть хэндл на тот же самый объект ядра.
- Операции
WaitOne()иReleaseMutex()взаимодействуют с этим общим объектом ОС, обеспечивая межпроцессную синхронизацию.
Пример использования именованного Mutex для межпроцессной синхронизации:
// Процесс A: Создает или открывает именованный мьютекс и захватывает его.
using (var mutex = new Mutex(initiallyOwned: true, name: "Global\MySingletonAppMutex"))
{
Console.WriteLine("Процесс A владеет мьютексом. Нажмите Enter для освобождения.");
Console.ReadLine();
mutex.ReleaseMutex();
}
// Процесс B: Открывает существующий мьютекс и пытается его захватить.
bool createdNew;
using (var mutex = new Mutex(initiallyOwned: false, name: "Global\MySingletonAppMutex", out createdNew))
{
Console.WriteLine($"Процесс B: Мьютекс создан заново? {createdNew}");
// Ожидаем, пока Процесс A освободит мьютекс.
Console.WriteLine("Процесс B ждет мьютекс...");
if (mutex.WaitOne(TimeSpan.FromSeconds(10)))
{
Console.WriteLine("Процесс B захватил мьютекс.");
mutex.ReleaseMutex();
}
}
Важные замечания:
- Префикс
Global\в Windows делает мьютекс видимым для всех сессий (полезно для служб). - Необходимо аккуратно обрабатывать исключения и всегда освобождать мьютекс в
finallyили с помощьюusing. - Межпроцессные мьютексы медленнее, чем внутрипроцессные блокировки, из-за переключения в режим ядра.