Kāda ir atšķirība starp semaforu un mutex?
sobes.tech AI
Atbilde no AI
Sēmafora ir vispārīgs sinhronizācijas mehānisms, kas tiek izmantots, lai pārvaldītu piekļuvi ierobežotam resursam vairākās konkurējošās pavedienos. Tas uztur veselu skaitli, kas samazinās, kad tiek ieņemts resurss, un palielinās, kad tas tiek atbrīvots. Ja semafora vērtība ir nulle, mēģinājums to ieņemt bloķē pavedienu, līdz cits pavedienis atbrīvos resursu. To var izmantot, lai ierobežotu vienlaicīgi darbojošo pavedienu skaitu.
MUTEX (mutual exclusion — savstarpēja izslēgšana) ir binārs semafors, kas var būt vai nu bloķēts, vai atbloķēts. To izmanto kritiskās sekcijas aizsardzībai pret vienlaicīgu piekļuvi no vairākiem pavedieniem. Tikai viens pavedienis var ieņemt mutex vienlaikus. Pavediens, kas ir ieguvis mutex, nevar tikt pārtraukts ar citu pavedienu, kurš mēģina to ieņemt. Ja mēģināsiet ieņemt bloķētu mutex, pavediens tiks bloķēts līdz tas tiks atbrīvots.
Galvenās atšķirības:
| Raksturlielums | Semafors | Mutex |
|---|---|---|
| Tips | Vispārīgs sinhronizācijas mehānisms | Binārs semafors (semafora īpašais gadījums) |
| Vērtība | Vesels skaitlis (>= 0) | Binārs (0 vai 1) |
| Mērķis | Piekļuves pārvaldība resursiem, ierobežojumi | Kritisko sekciju aizsardzība, savstarpēja izslēgšana |
| Īpašnieks | Var nebūt īpašnieks | Vienmēr ir īpašnieks (pavediens, kurš to ieguva) |
| Izmantošana iOS | DispatchSemaphore |
Bieži realizē caur DispatchQueue.sync vai NSRecursiveLock |
Piemērs, kā izmantot mutex kritiskās sekcijas aizsardzībai:
// GCD (Grand Central Dispatch) kontekstā
let serialQueue = DispatchQueue(label: "com.example.criticalSection")
serialQueue.sync {
// Kritiskās sekcijas kods
// Tikai viens pavedienis var būt šeit jebkurā laikā
}
Piemērs, kā izmantot semaforu paralēlo uzdevumu ierobežošanai:
// GCD (Grand Central Dispatch) kontekstā
let semaphore = DispatchSemaphore(value: 3) // Atļauj 3 paralēlas uzdevumus
DispatchQueue.global().async {
semaphore.wait() // Samazina semafora vērtību par 1. Bloķē, ja vērtība ir 0.
// Uzdevuma kods, kas tiek izpildīts paralēli
print("Uzdevums tiek izpildīts")
Thread.sleep(forTimeInterval: 1) // Darba imitācija
semaphore.signal() // Palielina semafora vērtību par 1. Atbrīvo gaidošo pavedienu, ja tāds ir.
print("Uzdevums pabeigts")
}
// Varat palaist vairākus šādus blokus. Tikai 3 tiks izpildīti vienlaikus.