Sobes.tech
Middle

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ě.