Sobes.tech
Middle

Co je to závodní podmínka (race condition)?

sobes.tech AI

Odpověď od AI

Stav závodu nastává, když dva nebo více vláken nebo procesů současně přistupují ke sdílenému zdroji (například proměnné, souboru, databázi) a výsledek operace závisí na pořadí, ve kterém tato vlákna/procesy vykonávají své akce. Kvůli nepředvídatelnému pořadí přístupu a změn dat může být výsledek nesprávný nebo neočekávaný.

Příklad v iOS: Předpokládejme, že máme čítač count, ke kterému současně přistupují dvě vlákna, aby ho zvýšila.

var count = 0

func incrementCount() {
    // Vlákno 1 načte count = 5
    // Vlákno 2 načte count = 5
    let currentCount = count
    // Vlákno 1 vypočítá newCount = 6
    // Vlákno 2 vypočítá newCount = 6
    let newCount = currentCount + 1
    // Vlákno 1 zapíše count = 6
    // Vlákno 2 zapíše count = 6 (přepsáním výsledku vlákna 1)
    count = newCount
}

// Pokud dvě vlákna současně zavolají incrementCount(),
// očekávaný výsledek bude count = 2,
// ale kvůli závodu může být count 1.

Pro zabránění závodům se používají synchronizační mechanismy:

  • Lock/Mu: Zablokuje přístup ke zdroji, dokud ho vlákno nepoužívá.
    import Foundation
    
    let lock = NSLock()
    var count = 0
    
    func incrementCount() {
        lock.lock() // Získání zámku
        let currentCount = count
        let newCount = currentCount + 1
        count = newCount
        lock.unlock() // Uvolnění zámku
    }
    
  • Fronty (Queues): Použití 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
        }
    }
    
  • Atomické operace: Neoddělitelné operace na úrovni instrukcí procesoru. Ve Swift lze použít OSAtomic... (zastaralé) nebo Atomic z @_implementationOnly import Atomics (experimentální), nebo přístupy založené na zámcích/frontách.

Výběr metody synchronizace závisí na konkrétním scénáři a požadavcích na výkon. Je důležité pochopit, že synchronizace může přidat další zátěž a v případě nesprávné implementace vést k vzájemným zámkům (deadlocks).