Sobes.tech
Middle

Mi a különbség a szemafor és a mutex között?

sobes.tech MI

Válasz az MI-től

A szemafor egy általános szinkronizációs mechanizmus, amelyet több versengő szál által korlátozott erőforrás hozzáférésének kezelésére használnak. Egészértékű értéket tart fenn, amely csökken az erőforrás elfoglalásakor és nő a felszabadításkor. Ha a szemafor értéke nulla, az elfoglalási kísérlet blokkolja a szálat, amíg egy másik szál nem szabadítja fel az erőforrást. Használható a párhuzamosan futó szálak számának korlátozására.

A mutex (mutual exclusion — kölcsönös kizárás) egy bináris szemafor, amely vagy zárolt, vagy feloldott állapotban lehet. A kritikus szekció védelmére szolgál, hogy több szál ne férhessen hozzá egyszerre. Csak egy szál foghatja a mutexet egy időben. A mutexet elfoglaló szálat nem szakíthatja meg más szál, amely ugyanazt a mutexet próbálja elfoglalni. Ha megpróbálja elfoglalni a zárolt mutexet, a szál blokkolva lesz annak feloldásáig.

Fő különbségek:

Jellemzők Szemafor Mutex
Típus Általános szinkronizációs mechanizmus Bináris szemafor (a szemafor egy speciális esete)
Érték Egészértékű (>= 0) Bináris (0 vagy 1)
Cél Hozzáférés kezelése erőforrásokhoz, korlátozás Kritikus szekciók védelme, kölcsönös kizárás
Tulajdonos Nem feltétlenül van tulajdonosa Mindig van tulajdonosa (a szál, amely elfoglalta)
Használat iOS-en DispatchSemaphore Gyakran DispatchQueue.sync vagy NSRecursiveLock segítségével valósítják meg néhány esetben

Példa a mutex használatára kritikus szekció védelmére:

// GCD (Grand Central Dispatch) kontextusában
let serialQueue = DispatchQueue(label: "com.example.criticalSection")

serialQueue.sync {
    // Kritikus szekció kódja
    // Csak egy szál lehet itt egy időben
}

Példa a szemafor használatára párhuzamos feladatok korlátozására:

// GCD (Grand Central Dispatch) kontextusában
let semaphore = DispatchSemaphore(value: 3) // 3 párhuzamos feladat engedélyezése

DispatchQueue.global().async {
    semaphore.wait() // Csökkenti a szemafor értékét 1-gyel. Blokkol, ha az érték 0.

    // A párhuzamosan végrehajtott feladat kódja
    print("Feladat fut")

    Thread.sleep(forTimeInterval: 1) // Munka imitálása

    semaphore.signal() // Növeli a szemafor értékét 1-gyel. Feloldja a várakozó szálakat, ha vannak.
    print("Feladat befejeződött")
}

// Több ilyen blokkot is indíthatunk. Csak 3 fog futni egyszerre.