Care este diferența dintre un semafor și un mutex?
sobes.tech AI
Răspuns de la AI
Semaforul este un mecanism de sincronizare generalizat utilizat pentru a gestiona accesul la resurse limitate de către mai multe fire concurente. Acesta păstrează o valoare întreagă care scade atunci când se preia resursa și crește atunci când se eliberează. Dacă valoarea semaforului este zero, încercarea de a-l prelua blochează firul până când alt fir eliberează resursa. Poate fi utilizat pentru a limita numărul de fire care lucrează simultan.
Mutex (excludere mutuală) este un semafor binar care poate fi în stare blocată sau deblocat. Este folosit pentru a proteja secțiunile critice ale codului împotriva accesului simultan de către mai multe fire. Doar un fir poate prelua mutex-ul într-un moment dat. Firul care a preluat mutex-ul nu poate fi întrerupt de alt fir care încearcă să-l preia. Dacă se încearcă preluarea unui mutex blocat, firul va fi blocat până când acesta este eliberat.
Diferențe cheie:
| Caracteristică | Semafor | Mutex |
|---|---|---|
| Tipul | Mecanism de sincronizare generalizat | Semafor binar (caz particular de semafor) |
| Valoare | Întreg (>= 0) | Binar (0 sau 1) |
| Scop | Controlul accesului la resurse, limitarea firelor | Protejarea secțiunilor critice, excludere mutuală |
| Proprietar | Poate nu avea proprietar | Are întotdeauna un proprietar (firul care l-a preluat) |
| Utilizare în iOS | DispatchSemaphore |
Adesea implementat prin DispatchQueue.sync sau NSRecursiveLock în anumite scenarii |
Exemplu de utilizare a unui mutex pentru protejarea unei secțiuni critice:
// În contextul GCD (Grand Central Dispatch)
let serialQueue = DispatchQueue(label: "com.example.criticalSection")
serialQueue.sync {
// Secțiunea critică a codului
// Doar un fir poate fi aici în orice moment
}
Exemplu de utilizare a unui semafor pentru limitarea sarcinilor paralele:
// În contextul GCD (Grand Central Dispatch)
let semaphore = DispatchSemaphore(value: 3) // Permite 3 sarcini în paralel
DispatchQueue.global().async {
semaphore.wait() // Scade valoarea semaforului cu 1. Blochează dacă valoarea este 0.
// Codul sarcinii paralele
print("Sarcină în curs")
Thread.sleep(forTimeInterval: 1) // Simulare de lucru
semaphore.signal() // Crește valoarea semaforului cu 1. Deblochează firul de așteptare, dacă există.
print("Sarcină finalizată")
}
// Se pot lansa mai multe astfel de blocuri. Doar 3 vor fi executate simultan.