Ce este o condiție de cursă (race condition)?
sobes.tech AI
Răspuns de la AI
Starea de condiție de cursă apare atunci când două sau mai multe fire sau procese accesează simultan o resursă comună (de exemplu, o variabilă, un fișier, o bază de date) și rezultatul operației depinde de ordinea în care aceste fire/procese își execută acțiunile. Din cauza ordinii imprevizibile de acces și modificare a datelor, rezultatul poate fi incorect sau neașteptat.
Exemplu în iOS:
Să presupunem că avem un contor count, la care accesează simultan două fire pentru a-l incrementa.
var count = 0
func incrementCount() {
// Firul 1 citește count = 5
// Firul 2 citește count = 5
let currentCount = count
// Firul 1 calculează newCount = 6
// Firul 2 calculează newCount = 6
let newCount = currentCount + 1
// Firul 1 scrie count = 6
// Firul 2 scrie count = 6 (suprascrie rezultatul Firului 1)
count = newCount
}
// Dacă două fire apelează incrementCount() simultan,
// rezultatul așteptat ar fi count = 2,
// dar din cauza condiției de cursă, count poate deveni 1.
Pentru a preveni condițiile de cursă, se folosesc mecanisme de sincronizare:
- Lock/Mușcă: Blochează accesul la resursă în timp ce firul o utilizează.
import Foundation let lock = NSLock() var count = 0 func incrementCount() { lock.lock() // Obține blocarea let currentCount = count let newCount = currentCount + 1 count = newCount lock.unlock() // Eliberează blocarea } - Cozi (Queues): Utilizarea cozilor secvențiale GCD.
import Foundation let serialQueue = DispatchQueue(label: "com.myapp.counterQueue") var count = 0 func incrementCount() { serialQueue.async { let currentCount = count let newCount = currentCount + 1 count = newCount } } - Operații atomice: Operații indivizibile la nivelul instrucțiunilor procesorului. În Swift, se poate folosi
OSAtomic...(învechit) sauAtomicdin@_implementationOnly import Atomics(experimentale), sau abordări bazate pe blocări/cozi.
Alegerea metodei de sincronizare depinde de scenariul specific și de cerințele de performanță. Este important să înțelegeți că sincronizarea poate introduce sarcină suplimentară și poate duce la blocaje reciproce (deadlocks) dacă nu este implementată corect.