Sobes.tech
Middle

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"
    }
}