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):
- Wzajemne wykluczenie (Mutual Exclusion): Zasób nie może być używany jednocześnie przez wiele procesów.
- 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.
- Brak preempcji (No Preemption): Zasoby nie mogą być wymuszenie odebrane wątkowi. Mogą być zwolnione tylko dobrowolnie przez wątek, który je posiada.
- 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
syncna kolejcemainz 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.")
}
}