Kuo skiriasi semaforas nuo mutex?
sobes.tech AI
Atsakymas iš AI
Semaforas yra bendras sinchronizacijos mechanizmas, naudojamas valdyti prieigą prie riboto ištekliaus kelių konkuruojančių srautų. Jis palaiko sveikąjį skaičių, kuris sumažėja, kai užimamas išteklius, ir padidėja, kai jis atlaisvinamas. Jei semaforo reikšmė lygi nuliui, bandymas jį užimti blokuoja srautą, kol kitas srautas neatlaisvins ištekliaus. Jis gali būti naudojamas riboti vienu metu veikiančių srautų skaičių.
MUTEX (mutual exclusion — tarpusavio išskyrimas) yra binarinis semaforas, kuris gali būti arba užblokuotas, arba atblokuotas. Jis naudojamas kritinės sekcijos apsaugai nuo kelių srautų vienalaikio prieigos. Tik vienas srautas gali užimti mutex vienu metu. Srautas, užėmęs mutex, negali būti nutrauktas kito srauto, kuris bando jį užimti. Jei bandysite užimti užblokuotą mutex, srautas bus blokuojamas iki jo atlaisvinimo.
Pagrindiniai skirtumai:
| Savybė | Semaforas | Mutex |
|---|---|---|
| Tipas | Bendras sinchronizacijos mechanizmas | Binarinis semaforas (ypatingas semaforo atvejis) |
| Reikšmė | Sveikasis skaičius (>= 0) | Binarinis (0 arba 1) |
| Paskirtis | Prieigos prie išteklių valdymas, apribojimas | Kritinių sekcijų apsauga, tarpusavio išskyrimas |
| Savininkas | Gali neturėti savininko | Visada turi savininką (srautas, kuris jį užėmė) |
| Naudojimas iOS | DispatchSemaphore |
Dažnai įgyvendinamas per DispatchQueue.sync arba NSRecursiveLock |
Pavyzdys, kaip naudoti mutex kritinei sekcijai apsaugoti:
// GCD (Grand Central Dispatch) kontekste
let serialQueue = DispatchQueue(label: "com.example.criticalSection")
serialQueue.sync {
// Kritinės sekcijos kodas
// Tik vienas srautas gali būti čia bet kuriuo metu
}
Pavyzdys, kaip naudoti semaforą paralelinių užduočių ribojimui:
// GCD (Grand Central Dispatch) kontekste
let semaphore = DispatchSemaphore(value: 3) // Leidžia 3 paralelines užduotis
DispatchQueue.global().async {
semaphore.wait() // Sumažina semaforo reikšmę 1-iu. Blokuoja, jei reikšmė yra 0.
// Užduoties kodas, vykdomas paraleliai
print("Užduotis vyksta")
Thread.sleep(forTimeInterval: 1) // Darbo imitacija
semaphore.signal() // Padidina semaforo reikšmę 1-iu. Atlaisvina laukiančią srautą, jei yra.
print("Užduotis baigta")
}
// Galite paleisti keletą tokių blokų. Tik 3 bus vykdomi vienu metu.