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