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.