Sobes.tech
Junior

Kas ir deadlock?

sobes.tech AI

Atbilde no AI

Dedloks (Deadlock) — tas stāvoklis, kad divi vai vairāk pavedieni vai procesi ir bloķēti, gaidot viens otru, lai varētu turpināt izpildi. Tas notiek, kad katrs pavediens ir ieguvis resursu, kas nepieciešams citam pavedienam, un pats gaida resursa atbrīvošanu, ko tur cits pavediens.

Četras nosacījumi, kas nepieciešami dedloka rašanās (Kofmana nosacījumi):

  1. Savstarpēja izslēgšana (Mutual Exclusion): Resurss nevar tikt izmantots vienlaicīgi vairākos procesos.
  2. Turēšana un gaidīšana (Hold and Wait): Pavediens, kuram jau ir vismaz viens resurss, gaida papildu resursus, kas pašlaik ir aizņemti ar citiem pavedieniem.
  3. Bez piespiedu atbrīvošanas (No Preemption): Resursi nevar tikt piespiedu kārtā atņemti pavedienam. Tie var tikt atbrīvoti tikai brīvprātīgi, to turētājs.
  4. Ciklisks gaidīšanas (Circular Wait): Pastāv ciklisks gaidīšanas cikls starp diviem vai vairāk pavedieniem. Piemēram, pavediens A gaida resursu, ko tur pavediens B, kas savukārt gaida resursu, ko tur pavediens C, kurš gaida resursu, ko tur pavediens A.

iOS izstrādē dedlokas bieži rodas, strādājot ar concurrency (vairāku pavedienu) funkcionalitāti, piemēram, nepareizi izmantojot GCD (Grand Central Dispatch) vai Operation Queue:

  • Mēģinājums sinhroni izpildīt koda bloku tajā rindā, kurā jau atrodas pašreizējais pavediens (piemēram, sync izsaukums main rindā no galvenā pavediena).
  • Divi pavedieni mēģina aizņemt divas dažādas slēdzenes vai semaforus dažādos secīgos.

Vienkāršs piemērs ar GCD izmantošanu:

func deadlockExample() {
    // Galvenā rinda
    let mainQueue = DispatchQueue.main

    // Sinhroni izpildīt bloku galvenajā rindā no galvenā pavediena
    // Galvenais pavediens gaida bloka pabeigšanu,
    // bet bloks nevar sākties, jo galvenais pavediens ir aizņemts ar gaidīšanu.
    mainQueue.sync {
        print("Šī rinda nekad netiks sasniegta.")
    }
}