Чем mutex и семафор отличаются от lock?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
lock в C# — это синтаксический сахар для использования Monitor.Enter и Monitor.Exit, обернутых в блок try-finally для гарантированного освобождения блокировки. Он предоставляет эксклюзивный доступ к ресурсу для одного потока. По сути, это простейший примитив синхронизации на уровне объекта.
Mutex (мьютекс) — это примитив синхронизации, который может использоваться для предоставления эксклюзивного доступа к ресурсу для одного потока потоков в нескольких процессах. Он имеет понятие владения потоком: только поток, который получил мьютекс, может его освободить.
Semaphore (семафор) — это примитив синхронизации, который ограничивает количество потоков, которые одновременно могут получить доступ к ресурсу. Семафор имеет счетчик, который уменьшается при получении доступа и увеличивается при его освобождении.
Основные отличия представлены в таблице:
| Характеристика | lock (Monitor) |
Mutex |
Semaphore |
|---|---|---|---|
| Сфера видимости | Внутри одного процесса | Между процессами | Между процессами |
| Количество потоков | Только один | Только один (владелец) | Ограниченное число |
| Владение | Привязано к потоку | Привязано к потоку | Не привязано к потоку |
| Использование | Простая синхронизация | Синхронизация между процессами, именованные мьютексы | Ограничение параллельного доступа к ресурсу |
| Исключения | Не требует явной обработки AbandonedMutexException | Требует обработки AbandonedMutexException | Нет AbandonedSemaphoreException |
// Пример использования lock
private readonly object _lockObject = new object();
public void DoSomethingWithLock()
{
lock (_lockObject)
{
// Критическая секция
}
}
// Пример использования Mutex
using System.Threading;
private Mutex _mutex = new Mutex();
public void DoSomethingWithMutex()
{
_mutex.WaitOne(); // Получить мьютекс
try
{
// Критическая секция
}
finally
{
_mutex.ReleaseMutex(); // Освободить мьютекс
}
}
// Пример использования Semaphore
using System.Threading;
private Semaphore _semaphore = new Semaphore(3, 3); // Разрешает 3 потокам одновременно
public void DoSomethingWithSemaphore()
{
_semaphore.WaitOne(); // Получить "доступ" семафора
try
{
// Критическая секция, доступ ограничен 3 потоками
}
finally
{
_semaphore.Release(); // Освободить "доступ"
}
}