Qual è la differenza tra un semaforo e un mutex?
sobes.tech AI
Risposta dell'AI
Il semaforo è un meccanismo di sincronizzazione generalizzato utilizzato per gestire l'accesso a risorse limitate da più thread concorrenti. Tiene un valore intero che diminuisce quando si acquisisce la risorsa e aumenta quando si rilascia. Se il valore del semaforo è zero, il tentativo di acquisirlo blocca il thread finché un altro thread non rilascia la risorsa. Può essere usato per limitare il numero di thread che lavorano contemporaneamente.
Un mutex (mutua esclusione) è un semaforo binario che può essere in uno stato bloccato o sbloccato. Viene usato per proteggere le sezioni critiche del codice da accessi simultanei di più thread. Solo un thread può acquisire il mutex in un dato momento. Il thread che ha acquisito il mutex non può essere interrotto da un altro thread che tenta di acquisirlo. Se si tenta di acquisire un mutex bloccato, il thread si blocca fino a quando non viene rilasciato.
Differenze chiave:
| Caratteristica | Semaforo | Mutex |
|---|---|---|
| Tipo | Meccanismo di sincronizzazione generalizzato | Semaforo binario (caso particolare di semaforo) |
| Valore | Intero (>= 0) | Binario (0 o 1) |
| Scopo | Controllo dell'accesso alle risorse, limitazione dei thread | Protezione delle sezioni critiche, mutua esclusione |
| Proprietario | Può non avere proprietario | Ha sempre un proprietario (thread che lo ha acquisito) |
| Uso in iOS | DispatchSemaphore |
Spesso implementato tramite DispatchQueue.sync o NSRecursiveLock in alcuni scenari |
Esempio di utilizzo di un mutex per proteggere una sezione critica:
// Nel contesto di GCD (Grand Central Dispatch)
let serialQueue = DispatchQueue(label: "com.example.criticalSection")
serialQueue.sync {
// Sezione critica del codice
// Solo un thread può essere qui in qualsiasi momento
}
Esempio di utilizzo di un semaforo per limitare le attività parallele:
// Nel contesto di GCD (Grand Central Dispatch)
let semaphore = DispatchSemaphore(value: 3) // Permette 3 attività parallele
DispatchQueue.global().async {
semaphore.wait() // Diminuisce il valore del semaforo di 1. Si blocca se il valore è 0.
// Codice dell'attività parallela
print("Attività in corso")
Thread.sleep(forTimeInterval: 1) // Simulazione di lavoro
semaphore.signal() // Aumenta il valore del semaforo di 1. Sblocca il thread in attesa, se presente.
print("Attività completata")
}
// Si possono avviare più di questi blocchi. Solo 3 saranno eseguiti contemporaneamente.