Sobes.tech
Middle

Qual é a diferença entre mutex, semáforo e lock?

sobes.tech IA

Resposta da IA

lock em C# é um açúcar sintático para usar Monitor.Enter e Monitor.Exit, envolvidos num bloco try-finally para garantir a libertação do bloqueio. Ele fornece acesso exclusivo a um recurso para um único thread. Em essência, é o primitive de sincronização mais simples ao nível do objeto.

Mutex é um primitive de sincronização que pode ser usado para fornecer acesso exclusivo a um recurso para um único thread de múltiplos processos. Tem um conceito de propriedade do thread: apenas o thread que obteve o mutex pode libertá-lo.

Semaphore é um primitive de sincronização que limita o número de threads que podem aceder a um recurso simultaneamente. Possui um contador que diminui ao obter acesso e aumenta ao libertar.

As principais diferenças são apresentadas na tabela:

Característica lock (Monitor) Mutex Semaphore
Escopo de visibilidade Dentro de um processo Entre processos Entre processos
Número de threads Apenas um Apenas um (proprietário) Número limitado
Propriedade Vinculado ao thread Vinculado ao thread Não vinculado ao thread
Uso Sincronização simples Sincronização entre processos, mutexes nomeados Limitação do acesso paralelo a um recurso
Exceções Não requer tratamento explícito de AbandonedMutexException Requer tratamento de AbandonedMutexException Não há AbandonedSemaphoreException
// Exemplo de uso de lock
private readonly object _lockObject = new object();

public void DoSomethingWithLock()
{
    lock (_lockObject)
    {
        // Seção crítica
    }
}

// Exemplo de uso de Mutex
using System.Threading;

private Mutex _mutex = new Mutex();

public void DoSomethingWithMutex()
{
    _mutex.WaitOne(); // Obter o mutex
    try
    {
        // Seção crítica
    }
    finally
    {
        _mutex.ReleaseMutex(); // Liberar o mutex
    }
}

// Exemplo de uso de Semaphore
using System.Threading;

private Semaphore _semaphore = new Semaphore(3, 3); // Permite 3 threads ao mesmo tempo

public void DoSomethingWithSemaphore()
{
    _semaphore.WaitOne(); // Obter "acesso" ao semáforo
    try
    {
        // Seção crítica, acesso limitado a 3 threads
    }
    finally
    {
        _semaphore.Release(); // Liberar "acesso"
    }
}