Sobes.tech
Middle

Čo je to závodná podmienka (race condition)?

sobes.tech AI

Odpoveď od AI

Stav trky nastáva, keď dva alebo viac vlákien alebo procesov súčasne pristupujú ku spoločnému zdroju (napríklad premennej, súboru, databáze) a výsledok operácie závisí od poradia, v akom tieto vlákna/procesy vykonávajú svoje akcie. Kvôli nepredvídateľnému poradiu prístupu a zmenám dát môže byť výsledok nesprávny alebo neočakávaný.

Príklad v iOS: Predpokladajme, že máme čítač count, ku ktorému súčasne pristupujú dve vlákna na inkrementáciu.

var count = 0

func incrementCount() {
    // Vlákno 1 načíta count = 5
    // Vlákno 2 načíta count = 5
    let currentCount = count
    // Vlákno 1 vypočíta newCount = 6
    // Vlákno 2 vypočíta newCount = 6
    let newCount = currentCount + 1
    // Vlákno 1 zapíše count = 6
    // Vlákno 2 zapíše count = 6 (prepíše výsledok Vlákna 1)
    count = newCount
}

// Ak dve vlákna zavolajú incrementCount() súčasne,
// očakávaný výsledok bude count = 2,
// ale kvôli stavu trky môže byť count rovný 1.

Na zabránenie stavov trky sa používajú mechanizmy synchronizácie:

  • Lock/Mutex: Zablokuje prístup ku zdroju, kým ho vlákno používa.
    import Foundation
    
    let lock = NSLock()
    var count = 0
    
    func incrementCount() {
        lock.lock() // Získanie zámku
        let currentCount = count
        let newCount = currentCount + 1
        count = newCount
        lock.unlock() // Uvoľnenie zámku
    }
    
  • Fronty (Queues): Použitie sekvenčných GCD front.
    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
        }
    }
    
  • Atómové operácie: Neporušiteľné operácie na úrovni inštrukcií procesora. Vo Swift-e je možné použiť OSAtomic... (zastaralé) alebo Atomic z @_implementationOnly import Atomics (eksperimentálne), alebo prístupy založené na zámkoch/frontoch.

Výber metódy synchronizácie závisí od konkrétneho scenára a požiadaviek na výkon. Dôležité je pochopiť, že synchronizácia môže priniesť dodatočné zaťaženie a potenciálne viesť k vzájomnému blokovaniu (deadlock), ak nie je správne implementovaná.