Šta je uslov trke (race condition)?
sobes.tech АИ
Одговор од АИ
Stanje trke nastaje kada dva ili više niti ili procesa istovremeno pristupaju zajedničkom resursu (na primer, promenljivoj, fajlu, bazi podataka) i rezultat operacije zavisi od reda u kojem te niti/procesi izvršavaju svoje radnje. Zbog nepredvidivog reda pristupa i izmene podataka, rezultat može biti netačan ili neočekivan.
Primer u iOS:
Pretpostavimo da imamo brojač count, kojem istovremeno pristupaju dve niti za inkrementaciju.
var count = 0
func incrementCount() {
// Nit 1 čita count = 5
// Nit 2 čita count = 5
let currentCount = count
// Nit 1 računa newCount = 6
// Nit 2 računa newCount = 6
let newCount = currentCount + 1
// Nit 1 zapisuje count = 6
// Nit 2 zapisuje count = 6 (prepisujući rezultat Nit 1)
count = newCount
}
// Ako dve niti pozovu incrementCount() istovremeno,
// očekivani rezultat bi bio count = 2,
// ali zbog stanja trke, count može postati 1.
Da bi se sprečila stanja trke, koriste se mehanizmi sinhronizacije:
- Lock/Mutex: Blokira pristup resursu dok ga nit koristi.
import Foundation let lock = NSLock() var count = 0 func incrementCount() { lock.lock() // Zauzimanje blokade let currentCount = count let newCount = currentCount + 1 count = newCount lock.unlock() // Oslobađanje blokade } - Redovi (Queues): Korišćenje sekvencijalnih GCD redova.
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 } } - Atomične operacije: Neprekinute operacije na nivou instrukcija procesora. U Swift-u se mogu koristiti
OSAtomic...(zastarjelo) iliAtomiciz@_implementationOnly import Atomics(eksperimentalno), ili pristupi zasnovani na blokadama/redovima.
Izbor metode sinhronizacije zavisi od konkretnog scenarija i zahteva za performanse. Važno je razumeti da sinhronizacija može doneti dodatno opterećenje i potencijalno dovesti do međuzaključavanja (deadlock), ako se ne implementira ispravno.