Qual é a diferença entre um semáforo e um mutex?
sobes.tech IA
Resposta da IA
O semáforo é um mecanismo de sincronização generalizado utilizado para gerir o acesso a recursos limitados por múltiplos threads concorrentes. Mantém um valor inteiro que diminui ao adquirir o recurso e aumenta ao libertar. Se o valor do semáforo for zero, a tentativa de o adquirir bloqueia o thread até que outro thread liberte o recurso. Pode ser usado para limitar o número de threads a trabalhar simultaneamente.
O mutex (exclusão mútua) é um semáforo binário que pode estar num estado bloqueado ou desbloqueado. É usado para proteger secções críticas do código contra acessos simultâneos por vários threads. Apenas um thread pode adquirir o mutex de cada vez. O thread que adquiriu o mutex não pode ser interrompido por outro thread que tente adquiri-lo. Se tentar adquirir um mutex bloqueado, o thread ficará bloqueado até que seja libertado.
Diferenças principais:
| Característica | Semáforo | Mutex |
|---|---|---|
| Tipo | Mecanismo de sincronização generalizado | Semáforo binário (caso particular de semáforo) |
| Valor | Inteiro (>= 0) | Binário (0 ou 1) |
| Propósito | Gestão de acesso a recursos, limitação de threads | Proteção de secções críticas, exclusão mútua |
| Proprietário | Pode não ter proprietário | Tem sempre proprietário (thread que o adquiriu) |
| Uso em iOS | DispatchSemaphore |
Frequentemente implementado através de DispatchQueue.sync ou NSRecursiveLock em alguns cenários |
Exemplo de uso de mutex para proteger uma secção crítica:
// No contexto de GCD (Grand Central Dispatch)
let serialQueue = DispatchQueue(label: "com.example.criticalSection")
serialQueue.sync {
// Secção crítica do código
// Apenas um thread pode estar aqui de cada vez
}
Exemplo de uso de semáforo para limitar tarefas paralelas:
// No contexto de GCD (Grand Central Dispatch)
let semaphore = DispatchSemaphore(value: 3) // Permite 3 tarefas em paralelo
DispatchQueue.global().async {
semaphore.wait() // Diminui o valor do semáforo em 1. Bloqueia se o valor for 0.
// Código da tarefa em paralelo
print("Tarefa em execução")
Thread.sleep(forTimeInterval: 1) // Simulação de trabalho
semaphore.signal() // Aumenta o valor do semáforo em 1. Desbloqueia o thread em espera, se houver.
print("Tarefa concluída")
}
// Pode lançar vários desses blocos. Apenas 3 irão executar-se ao mesmo tempo.