Sobes.tech
Middle

Kas ir sacīkšu stāvoklis (race condition)?

sobes.tech AI

Atbilde no AI

Riska stāvoklis rodas, kad divi vai vairāk pavedieni vai procesi vienlaikus piekļūst kopīgam resursam (piemēram, mainīgajam, failam, datu bāzei), un operācijas rezultāts ir atkarīgs no tā, kādā secībā šie pavedieni/procesi veic savas darbības. Dēļ nenoteiktās piekļuves un datu modifikācijas secības rezultāts var būt nepareizs vai negaidīts:

Piemērs iOS: Pieņemsim, mums ir skaitītājs count, kam vienlaikus piekļūst divi pavedieni, lai palielinātu:

var count = 0

func incrementCount() {
    // Pirmais pavedienis lasa count = 5
    // Otrais pavedienis lasa count = 5
    let currentCount = count
    // Pirmais pavedienis aprēķina jauno skaitli = 6
    // Otrais pavedienis aprēķina jauno skaitli = 6
    let newCount = currentCount + 1
    // Pirmais pavedienis ieraksta count = 6
    // Otrais pavedienis ieraksta count = 6 (pārklājot pirmā rezultātu)
    count = newCount
}

// Ja divi pavedieni vienlaikus izsauc incrementCount(),
// sagaidāmais rezultāts būtu count = 2,
// bet, ņemot vērā sacensību stāvokli, count var būt 1.

Lai novērstu sacensību stāvokli, tiek izmantoti sinhronizācijas mehānismi:

  • Lock/Mutex: Bloķē piekļuvi resursam, kamēr to izmanto pavediens:
    import Foundation
    
    let lock = NSLock()
    var count = 0
    
    func incrementCount() {
        lock.lock() // Bloķēt
        let currentCount = count
        let newCount = currentCount + 1
        count = newCount
        lock.unlock() // Atbrīvot
    }
    
  • Rindas (Queues): Izmantojot secīgas GCD rindas:
    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
        }
    }
    
  • Atomu operācijas: Neatkarīgas operācijas uz procesora instrukciju līmeņa. Swift var izmantot OSAtomic... (novecojis) vai Atomic no @_implementationOnly import Atomics (eksperimentāls), vai pieejas, kas balstītas uz bloķēšanu/rindām:

Izvēle ir atkarīga no konkrētā scenārija un veiktspējas prasībām. Svarīgi ir saprast, ka sinhronizācija var palielināt slodzi un potenciāli novest pie mīlestības bloķēšanas (deadlock), ja tā tiek īstenota nepareizi.