Czym różnią się mutex i semafor od lock?
sobes.tech AI
Odpowiedź od AI
lock w C# jest cukierkiem składniowym do używania Monitor.Enter i Monitor.Exit, opakowanych w blok try-finally, aby zagwarantować zwolnienie blokady. Zapewnia wyłączny dostęp do zasobu dla jednego wątku. W istocie jest to najprostszy prymityw synchronizacji na poziomie obiektu.
Mutex to prymityw synchronizacji, który może być używany do zapewnienia wyłącznego dostępu do zasobu dla pojedynczego wątku w wielu procesach. Ma pojęcie własności wątku: tylko wątek, który uzyskał mutex, może go zwolnić.
Semaphore to prymityw synchronizacji, który ogranicza liczbę wątków, które mogą jednocześnie uzyskać dostęp do zasobu. Ma licznik, który zmniejsza się przy uzyskaniu dostępu i zwiększa przy jego zwolnieniu.
Główne różnice przedstawione są w tabeli:
| Charakterystyka | lock (Monitor) |
Mutex |
Semaphore |
|---|---|---|---|
| Zakres widoczności | Wewnątrz jednego procesu | Między procesami | Między procesami |
| Liczba wątków | Tylko jeden | Tylko jeden (właściciel) | Ograniczona liczba |
| Własność | Powiązana z wątkiem | Powiązana z wątkiem | Nie powiązana z wątkiem |
| Użycie | Prosta synchronizacja | Synchronizacja między procesami, nazwane mutexy | Ograniczenie równoczesnego dostępu do zasobu |
| Wyjątki | Nie wymaga jawnego obsługi AbandonedMutexException | Wymaga obsługi AbandonedMutexException | Brak AbandonedSemaphoreException |
// Przykład użycia lock
private readonly object _lockObject = new object();
public void DoSomethingWithLock()
{
lock (_lockObject)
{
// Sekcja krytyczna
}
}
// Przykład użycia Mutex
using System.Threading;
private Mutex _mutex = new Mutex();
public void DoSomethingWithMutex()
{
_mutex.WaitOne(); // Uzyskać mutex
try
{
// Sekcja krytyczna
}
finally
{
_mutex.ReleaseMutex(); // Zwolnić mutex
}
}
// Przykład użycia Semaphore
using System.Threading;
private Semaphore _semaphore = new Semaphore(3, 3); // Pozwala na 3 wątki jednocześnie
public void DoSomethingWithSemaphore()
{
_semaphore.WaitOne(); // Uzyskać "dostęp" do semafora
try
{
// Sekcja krytyczna, ograniczona do 3 wątków
}
finally
{
_semaphore.Release(); // Zwolnić "dostęp"
}
}