Sobes.tech
Middle

Kas yra lenktynių sąlyga (race condition)?

sobes.tech AI

Atsakymas iš AI

Rizikos būklė atsiranda, kai du ar daugiau sriegių arba procesų vienu metu prieina prie bendro išteklio (pavyzdžiui, kintamojo, failo, duomenų bazės) ir operacijos rezultatas priklauso nuo to, kaip tvarkingai šie sriegių/procesų vykdymas. Dėl nenuspėjamo prieigos ir duomenų keitimo tvarkos rezultatas gali būti netikslus arba netikėtas:

Pavyzdys iOS: Tarkime, turime skaitiklį count, prie kurio vienu metu prieina du sriegių:

var count = 0

func incrementCount() {
    // Pirmas sraigas skaito count = 5
    // Antras sraigas skaito count = 5
    let currentCount = count
    // Pirmas sraigas skaičiuoja newCount = 6
    // Antras sraigas skaičiuoja newCount = 6
    let newCount = currentCount + 1
    // Pirmas sraigas įrašo count = 6
    // Antras sraigas įrašo count = 6 (perrašydamas pirmojo rezultatą)
    count = newCount
}

// Jei du sriegių vienu metu iškvies incrementCount(),
// tikėtinas rezultatas būtų count = 2,
// tačiau dėl varžybų būklės, count gali būti 1.

Siekiant išvengti varžybų būklės, naudojami sinchronizacijos mechanizmai:

  • Lock/Mutex: Blokuoja prieigą prie ištekliaus, kol jį naudoja sraigas:
    import Foundation
    
    let lock = NSLock()
    var count = 0
    
    func incrementCount() {
        lock.lock() // Užrakinti
        let currentCount = count
        let newCount = currentCount + 1
        count = newCount
        lock.unlock() // Atskilti
    }
    
  • Eilės (Queues): Naudojant sekcines GCD eilutes:
    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
        }
    }
    
  • Atomines operacijos: Nepertraukiamos operacijos procesoriaus instrukcijų lygyje. Swift galima naudoti OSAtomic... (pasenęs) arba Atomic@_implementationOnly import Atomics (eksperimentinis), arba sprendimus, pagrįstus užrakinimais/eilėmis:

Pasirinkimas priklauso nuo konkretaus scenarijaus ir našumo reikalavimų. Svarbu suprasti, kad sinchronizacija gali pridėti papildomą apkrovą ir potencialiai sukelti mirties užraktus (deadlocks), jei įgyvendinama netinkamai.