Sobes.tech
Junior

Kas yra deadlock?

sobes.tech AI

Atsakymas iš AI

Dėdlokas (Deadlock) — tai būsena, kai du ar daugiau srautų arba procesų yra užblokuoti, laukdami vienas kito, kad galėtų tęsti vykdymą. Tai įvyksta, kai kiekvienas srautas turi išteklių, kuris reikalingas kitam srautui, ir pats laukia išlaisvinimo išteklių, kurį laiko kitas srautas.

Keturi sąlygos, būtinos dėdloko atsiradimui (Kofmano sąlygos):

  1. Tarpusavio išskirtinumas (Mutual Exclusion): Išteklis negali būti naudojamas vienu metu kelių procesų.
  2. Laikymas ir laukimas (Hold and Wait): Srautas, jau turintis bent vieną išteklių, laukia papildomų išteklių, kurie šiuo metu yra užimti kitų srautų.
  3. Be prievartos (No Preemption): Ištekliai negali būti prievarta paimti iš srauto. Jie gali būti atlaisvinti tik savanoriškai turo, kuris juos turi.
  4. Ciklinis laukimas (Circular Wait): Yra ciklas laukiančių tarp dviejų ar daugiau srautų. Pavyzdžiui, Srautas A laukia ištekliaus, kurį laiko Srautas B, kuris savo ruožtu laukia ištekliaus, kurį laiko Srautas C, kuris laukia ištekliaus, kurį laiko Srautas A.

iOS kūrime dėdlokai dažnai atsiranda dirbant su concurrency (daugiasraute), pavyzdžiui, netinkamai naudojant GCD (Grand Central Dispatch) arba Operation Queue:

  • Bandymas sinchroniškai vykdyti kodo bloką toje eilėje, kurioje jau yra dabartinis srautas (pavyzdžiui, sync iškvietimas main eilėje iš pagrindinio srauto).
  • Du srautai bando užimti du skirtingus užraktus arba semaforus skirtingais būdais.

Pavyzdys paprasto dėdloko naudojant GCD:

func deadlockExample() {
    // Pagrindinė eilė
    let mainQueue = DispatchQueue.main

    // Sinchroniškai vykdyti bloką pagrindinėje eilėje iš pagrindinio srauto
    // Pagrindinis srautas laukia bloko pabaigos,
    // o blokas negali pradėti, nes pagrindinis srautas užimtas laukimu.
    mainQueue.sync {
        print("Šis eilutė niekada nebus pasiekta.")
    }
}