Sobes.tech
Middle

Aký je rozdiel medzi semaforom a mutexom?

sobes.tech AI

Odpoveď od AI

Semafor je všeobecný mechanizmus synchronizácie používaný na riadenie prístupu k obmedzenému zdroju viacerými konkurenčnými vláknami. Udržiava celočíselnú hodnotu, ktorá sa znižuje pri zachytení zdroja a zvyšuje pri jeho uvoľnení. Ak je hodnota semaforu rovná nule, pokus o zachytenie blokuje vlákno, kým iné vlákno neuvoľní zdroj. Môže sa použiť na obmedzenie počtu súčasne bežiacich vlákien.

Mutex (mutual exclusion — vzájomné vylúčenie) je binárny semafor, ktorý môže byť buď zablokovaný, alebo odblokovaný. Používa sa na ochranu kritickej sekcie pred súčasným prístupom viacerých vlákien. Len jedno vlákno môže získať mutex v danom okamihu. Vlákno, ktoré získalo mutex, nemôže byť prerušené iným vláknom, ktoré sa snaží získať ten istý mutex. Ak sa pokúsite získať zablokovaný mutex, vlákno bude zablokované do jeho uvoľnenia.

Kľúčové rozdiely:

Charakteristika Semafor Mutex
Typ Všeobecný mechanizmus synchronizácie Binárny semafor (špeciálny prípad semaforu)
Hodnota Celočíselná (>= 0) Binárna (0 alebo 1)
Účel Riadenie prístupu k zdrojom, obmedzenie Ochrana kritických sekcií, vzájomné vylúčenie
Vlastník Môže nemieť vlastníka Vždy má vlastníka (vlákno, ktoré ho získalo)
Použitie v iOS DispatchSemaphore Často sa realizuje cez DispatchQueue.sync alebo NSRecursiveLock v niektorých scénaroch

Príklad použitia mutexu na ochranu kritickej sekcie:

// V kontexte GCD (Grand Central Dispatch)
let serialQueue = DispatchQueue(label: "com.example.criticalSection")

serialQueue.sync {
    // Kritická sekcia kódu
    // Len jedno vlákno môže byť tu v akomkoľvek momente
}

Príklad použitia semaforu na obmedzenie paralelných úloh:

// V kontexte GCD (Grand Central Dispatch)
let semaphore = DispatchSemaphore(value: 3) // Povolenie 3 paralelných úloh

DispatchQueue.global().async {
    semaphore.wait() // Znižuje hodnotu semaforu o 1. Blokuje, ak je hodnota = 0.

    // Kód úlohy vykonávanej paralelne
    print("Úloha sa vykonáva")

    Thread.sleep(forTimeInterval: 1) // Imitácia práce

    semaphore.signal() // Zvyšuje hodnotu semaforu o 1. Uvoľňuje čakajúce vlákno, ak existuje.
    print("Úloha dokončená")
}

// Môžete spustiť niekoľko takýchto blokov. Len 3 budú vykonávané súčasne.