Ce face sincronizarea în contextul multitreading-ului?
sobes.tech AI
Răspuns de la AI
Sincronizarea în contextul multitreading-ului previne condițiile de cursă (race condition) și asigură un acces coerent la resursele comune (variabile, fișiere, conexiuni de rețea) din mai multe fire.
Principalele mecanisme de sincronizare:
- Mutex (excludere mutuală): Doar un fir poate deține mutex-ul și poate accesa resursa protejată.
- Semaphore (semafor): Limitează numărul de fire care pot accesa simultan o resursă. Funcționează cu un contor.
- Lock (blocare): Concept generalizat, adesea folosit pentru a desemna mutex-uri sau alte mecanisme care blochează complet accesul.
- Dispatch Queue (coadă de dispatch): În Grand Central Dispatch (GCD), coada poate fi secvențială (serial) sau concurentă (concurrent), asigurând sincronizarea prin controlul ordinii și numărului de sarcini executate simultan. Cozile secvențiale garantează executarea sarcinilor una câte una, oferind în mod inerent sincronizare pentru datele accesate doar din sarcinile acestei cozi.
Principiul de funcționare: Un fir care dorește să acceseze o resursă comună încearcă mai întâi să obțină o blocare (lock). Dacă resursa este liberă, firul obține blocarea și lucrează cu resursa. La final, eliberază blocarea (release lock). Dacă resursa este ocupată, alte fire se blochează (așteaptă) până când resursa devine liberă.
Exemplu de utilizare a unui mutex pentru protejarea unei secțiuni critice:
// Exemplu în Objective-C folosind @synchronized
- (void)updateSharedResource {
@synchronized (self) { // Blocare pe obiectul self
// Aici se execută secțiunea critică
// Accesul la sharedResource este sigur
self.sharedResource++;
} // Blocarea se eliberează automat la ieșirea din bloc
}
// Exemplu în Swift folosind NSLock
let lock = NSLock()
var sharedCounter = 0
func incrementCounter() {
lock.lock() // Încercare de a obține blocarea
// Secțiune critică
sharedCounter += 1
lock.unlock() // Eliberare blocare
}
Sintezarea ajută la evitarea problemelor precum:
- Corupția datelor.
- Deadlock (blocarea reciprocă) a firelor.
- Livelock (blocaje active) a firelor.
Alegerea mecanismului de sincronizare potrivit depinde de natura sarcinii și de tipul resursei.