Jaký je rozdíl mezi semaforem a mutexem?
sobes.tech AI
Odpověď od AI
Semafor je obecným synchronizačním mechanismem používaným k řízení přístupu ke sdílenému zdroji mezi více konkurenčními vlákny. Udržuje celočíselnou hodnotu, která se snižuje při získání zdroje a zvyšuje při jeho uvolnění. Pokud je hodnota semaforu rovna nule, pokus o získání blokuje vlákno, dokud jiné vlákno neuvolní zdroj. Může být použito k omezení počtu současně běžících vláken.
Mutex (mutual exclusion — vzájemné vyloučení) je binární semafor, který může být buď zablokován, nebo odblokován. Používá se k ochraně kritické sekce kódu před současným přístupem více vláken. Pouze jedno vlákno může získat mutex v daném okamžiku. Vlákno, které získalo mutex, nemůže být přerušeno jiným vláknem, které se snaží získat ten samý mutex. Pokud se pokusí získat zablokovaný mutex, vlákno bude zablokováno do jeho uvolnění.
Klíčové rozdíly:
| Charakteristika | Semafor | Mutex |
|---|---|---|
| Typ | Obecný mechanismus synchronizace | Binární semafor (speciální případ semaforu) |
| Hodnota | Celočíselná (>= 0) | Binární (0 nebo 1) |
| Účel | Řízení přístupu ke zdrojům, omezení vláken | Ochrana kritických sekcí, vzájemné vyloučení |
| Vlastník | Může nemít vlastníka | Vždy má vlastníka (vlákno, které jej získalo) |
| Použití v iOS | DispatchSemaphore |
Často implementováno přes DispatchQueue.sync nebo NSRecursiveLock v některých scénářích |
Příklad použití mutexu k ochraně kritické sekce:
// V kontextu GCD (Grand Central Dispatch)
let serialQueue = DispatchQueue(label: "com.example.criticalSection")
serialQueue.sync {
// Kritická sekce kódu
// Pouze jedno vlákno může být zde v jakémkoli okamžiku
}
Příklad použití semaforu k omezení paralelních úloh:
// V kontextu GCD (Grand Central Dispatch)
let semaphore = DispatchSemaphore(value: 3) // Povolení 3 paralelních úloh
DispatchQueue.global().async {
semaphore.wait() // Snižuje hodnotu semaforu o 1. Blokuje, pokud je hodnota = 0.
// Kód úlohy prováděné paralelně
print("Úloha se provádí")
Thread.sleep(forTimeInterval: 1) // Napodobení práce
semaphore.signal() // Zvyšuje hodnotu semaforu o 1. Odblokuje čekající vlákno, pokud existuje.
print("Úloha dokončena")
}
// Můžete spustit několik takových bloků. Pouze 3 poběží současně.