Sobes.tech
Junior

Czym jest deadlock?

sobes.tech AI

Odpowiedź od AI

Deadlock (zakleszczenie) to stan, w którym dwa lub więcej wątków lub procesów blokuje się nawzajem, oczekując na zwolnienie zasobu, aby kontynuować wykonywanie. Występuje, gdy każdy wątek posiada zasób, którego potrzebuje inny wątek, i czeka na zwolnienie tego zasobu.

Cztery warunki konieczne do wystąpienia deadlocka (warunki Coffmana):

  1. Wzajemne wykluczenie (Mutual Exclusion): Zasób nie może być używany jednocześnie przez wiele procesów.
  2. Zatrzymanie i oczekiwanie (Hold and Wait): Wątek, który już posiada co najmniej jeden zasób, oczekuje na dodatkowe zasoby, które są zajęte przez inne wątki.
  3. Brak preempcji (No Preemption): Zasoby nie mogą być wymuszenie odebrane wątkowi. Mogą być zwolnione tylko dobrowolnie przez wątek, który je posiada.
  4. Cykl oczekiwania (Circular Wait): Istnieje cykl oczekiwań między dwoma lub więcej wątkami. Na przykład, wątek A oczekuje zasobu, który posiada wątek B, który z kolei oczekuje zasobu, który posiada wątek C, który oczekuje zasobu, który posiada wątek A.

W rozwoju iOS deadlocki często występują podczas pracy z konkurencją, na przykład przy niewłaściwym użyciu GCD (Grand Central Dispatch) lub kolejek operacji:

  • Próba synchronicznego wykonania bloku kodu na kolejce, na której już znajduje się bieżący wątek (np. wywołanie sync na kolejce main z głównego wątku).
  • Dwa wątki próbują przejąć dwa różne zamki lub semafory w różnej kolejności.

Przykład prostego deadlocka z użyciem GCD:

func deadlockExample() {
    // Kolej główna
    let mainQueue = DispatchQueue.main

    // Wykonanie synchronicznego bloku na kolejce głównej z głównego wątku
    // Główny wątek oczekuje na zakończenie bloku,
    // a blok nie może się uruchomić, ponieważ główny wątek jest zajęty oczekiwaniem.
    mainQueue.sync {
        print("Ta linia nigdy nie zostanie osiągnięta.")
    }
}