Sobes.tech
Junior

Mis on deadlock?

sobes.tech AI

Vastus AI-lt

Düük — see on ummikseis oluk mitme lõimega programmeerimises, kus kaks või enam lõime blokeerivad üksteist, oodates ressursse, mida teised samasse gruppi kuuluvad lõimed kasutavad.

Düükide tekkimise tingimused (Koffmani tingimused):

  1. Vastastikune välistus (Mutual Exclusion): Ressursse ei saa kasutada samaaegselt mitme lõime poolt.
  2. Hoidmine ja ootamine (Hold and Wait): Ressursi juba omav lõim ootab täiendavat ressurssi, mida kasutab teine lõim.
  3. Ilma eelneva äravõtmiseta (No Preemption): Ressurssi ei saa sunniviisiliselt lõigata lõimelt, kes seda omab; seda saab vabastada ainult lõim ise.
  4. Ringiline ootamine (Circular Wait): On olemas ahel kahe või enama lõime vahel, kus iga lõim ootab ressursi, mida omab järgmine lõim ahelas (põhimõtteliselt, ootamine "ringis").

Lihtne näide düüük:

Kaks lõime, kaks ressurssi (A ja B).

  • Lõim 1 omab ressurssi A.
  • Lõim 2 omab ressurssi B.
  • Lõim 1 püüab omandada ressurssi B (mis on hõivatud Lõim 2 poolt).
  • Lõim 2 püüab omandada ressurssi A (mis on hõivatud Lõim 1 poolt).

Mõlemad lõimed on igaveseks blokeeritud.

// Lihtne düüük simulatsiooni näide lock kasutades
object resourceA = new object();
object resourceB = new object();

void Thread1Method()
{
    lock (resourceA) // Lõim 1 omab A-d
    {
        Console.WriteLine("Lõim 1 omandas ressursi A");
        Thread.Sleep(100); // Väike viivitus, et näidata lõimede vahetamise võimalust
        lock (resourceB) // Lõim 1 püüab omandada B-d
        {
            Console.WriteLine("Lõim 1 omandas ressursi B");
        }
    }
}

void Thread2Method()
{
    lock (resourceB) // Lõim 2 omab B-d
    {
        Console.WriteLine("Lõim 2 omandas ressursi B");
        Thread.Sleep(100); // Väike viivitus
        lock (resourceA) // Lõim 2 püüab omandada A-d
        {
            Console.WriteLine("Lõim 2 omandas ressursi A");
        }
    }
}

// Sõlmede loomine ja käivitamine võib viia düüükini.
// new Thread(Thread1Method).Start();
// new Thread(Thread2Method).Start();

// Selle koodi käivitamine võib, kuid ei pruugi, näidata düüükki,
// kuna täitmise järjekord sõltub planeerijast.
// Kui Lõim 1 omab A-d ja Lõim 2 B-d enne, kui esimene
// suudab omandada B-d, tekib düüük.

Düüükide ennetamine saavutatakse sageli:

  • Ressursside hankimise järjekorra standardiseerimisega (alati hankida ressursid samas järjekorras).
  • Kasutades ajapiiranguga ressursi hankimise meetodeid (proovida ressursi hankida kindla aja jooksul).
  • Disainides süsteemi ilma vajaduseta hoida mitu lukku samaaegselt.
  • Kasutades atomaarseid operatsioone või kõrgema taseme sünkroniseerimise primitiive (näiteks, Monitor.TryEnter, ReaderWriterLockSlim).

Düüükid on raskesti diagnoositavad, kuna need sõltuvad lõimede täitmise järjekorrast ja ilmnevad sageli ainult koormuse all. Visual Studio pakub tööriistu nende avastamiseks ja analüüsiks.